rb4xx.patch 661 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253
  1. diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig
  2. --- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200
  3. +++ linux-2.6.39/arch/mips/Kconfig 2011-08-24 18:17:24.000000000 +0200
  4. @@ -84,6 +84,23 @@
  5. help
  6. Support for the Atheros AR71XX/AR724X/AR913X SoCs.
  7. +config ATHEROS_AR71XX
  8. + bool "Atheros AR71xx based boards"
  9. + select CEVT_R4K
  10. + select CSRC_R4K
  11. + select DMA_NONCOHERENT
  12. + select HW_HAS_PCI
  13. + select IRQ_CPU
  14. + select ARCH_REQUIRE_GPIOLIB
  15. + select SYS_HAS_CPU_MIPS32_R1
  16. + select SYS_HAS_CPU_MIPS32_R2
  17. + select SYS_SUPPORTS_32BIT_KERNEL
  18. + select SYS_SUPPORTS_BIG_ENDIAN
  19. + select SYS_HAS_EARLY_PRINTK
  20. + select MIPS_MACHINE
  21. + help
  22. + Support for Atheros AR71xx based boards.
  23. +
  24. config BCM47XX
  25. bool "Broadcom BCM47XX based boards"
  26. select CEVT_R4K
  27. @@ -739,6 +756,7 @@
  28. endchoice
  29. source "arch/mips/alchemy/Kconfig"
  30. +source "arch/mips/ar71xx/Kconfig"
  31. source "arch/mips/ath79/Kconfig"
  32. source "arch/mips/bcm63xx/Kconfig"
  33. source "arch/mips/jazz/Kconfig"
  34. @@ -907,6 +925,9 @@
  35. config MIPS_DISABLE_OBSOLETE_IDE
  36. bool
  37. +config MYLOADER
  38. + bool
  39. +
  40. config SYNC_R4K
  41. bool
  42. diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile
  43. --- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200
  44. +++ linux-2.6.39/arch/mips/Makefile 2011-08-24 18:17:24.000000000 +0200
  45. @@ -158,6 +158,13 @@
  46. endif
  47. cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
  48. +#
  49. +# Atheros AR71xx
  50. +#
  51. +core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
  52. +cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
  53. +load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
  54. +
  55. cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
  56. cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
  57. cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
  58. @@ -174,6 +181,7 @@
  59. #
  60. libs-$(CONFIG_ARC) += arch/mips/fw/arc/
  61. libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
  62. +libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/
  63. libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
  64. libs-y += arch/mips/fw/lib/
  65. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig
  66. --- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  67. +++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-08-24 18:17:23.000000000 +0200
  68. @@ -0,0 +1,420 @@
  69. +if ATHEROS_AR71XX
  70. +
  71. +menu "Atheros AR71xx machine selection"
  72. +
  73. +config AR71XX_MACH_AP81
  74. + bool "Atheros AP81 board support"
  75. + select SOC_AR913X
  76. + select AR71XX_DEV_M25P80
  77. + select AR71XX_DEV_AR9XXX_WMAC
  78. + select AR71XX_DEV_GPIO_BUTTONS
  79. + select AR71XX_DEV_LEDS_GPIO
  80. + select AR71XX_DEV_USB
  81. + default n
  82. +
  83. +config AR71XX_MACH_AP83
  84. + bool "Atheros AP83 board support"
  85. + select SOC_AR913X
  86. + select AR71XX_DEV_AR9XXX_WMAC
  87. + select AR71XX_DEV_GPIO_BUTTONS
  88. + select AR71XX_DEV_LEDS_GPIO
  89. + select AR71XX_DEV_USB
  90. + default n
  91. +
  92. +config AR71XX_MACH_AP96
  93. + bool "Atheros AP96 board support"
  94. + select SOC_AR71XX
  95. + select AR71XX_DEV_M25P80
  96. + select AR71XX_DEV_AP94_PCI if PCI
  97. + select AR71XX_DEV_GPIO_BUTTONS
  98. + select AR71XX_DEV_LEDS_GPIO
  99. + select AR71XX_DEV_USB
  100. + default n
  101. +
  102. +config AR71XX_MACH_AP121
  103. + bool "Atheros AP121 board support"
  104. + select AR71XX_DEV_M25P80
  105. + select AR71XX_DEV_GPIO_BUTTONS
  106. + select AR71XX_DEV_LEDS_GPIO
  107. + select AR71XX_DEV_USB
  108. + select AR71XX_DEV_AR9XXX_WMAC
  109. + select SOC_AR933X
  110. + default n
  111. +
  112. +config AR71XX_MACH_DB120
  113. + bool "Atheros DB120 board support"
  114. + select SOC_AR934X
  115. + select AR71XX_DEV_AR9XXX_WMAC
  116. + select AR71XX_DEV_DB120_PCI if PCI
  117. + select AR71XX_DEV_GPIO_BUTTONS
  118. + select AR71XX_DEV_LEDS_GPIO
  119. + select AR71XX_DEV_USB
  120. + default n
  121. +
  122. +config AR71XX_MACH_DIR_600_A1
  123. + bool "D-Link DIR-600 rev. A1 support"
  124. + select SOC_AR724X
  125. + select AR71XX_DEV_AP91_PCI if PCI
  126. + select AR71XX_DEV_M25P80
  127. + select AR71XX_DEV_GPIO_BUTTONS
  128. + select AR71XX_DEV_LEDS_GPIO
  129. + select AR71XX_NVRAM
  130. + default n
  131. +
  132. +config AR71XX_MACH_DIR_615_C1
  133. + bool "D-Link DIR-615 rev. C1 support"
  134. + select SOC_AR913X
  135. + select AR71XX_DEV_M25P80
  136. + select AR71XX_DEV_AR9XXX_WMAC
  137. + select AR71XX_DEV_GPIO_BUTTONS
  138. + select AR71XX_DEV_LEDS_GPIO
  139. + select AR71XX_NVRAM
  140. + default n
  141. +
  142. +config AR71XX_MACH_DIR_825_B1
  143. + bool "D-Link DIR-825 rev. B1 board support"
  144. + select SOC_AR71XX
  145. + select AR71XX_DEV_M25P80
  146. + select AR71XX_DEV_AP94_PCI if PCI
  147. + select AR71XX_DEV_GPIO_BUTTONS
  148. + select AR71XX_DEV_LEDS_GPIO
  149. + select AR71XX_DEV_USB
  150. + default n
  151. +
  152. +config AR71XX_MACH_JA76PF
  153. + bool "jjPlus JA76PF board support"
  154. + select SOC_AR71XX
  155. + select AR71XX_DEV_M25P80
  156. + select AR71XX_DEV_GPIO_BUTTONS
  157. + select AR71XX_DEV_PB42_PCI if PCI
  158. + select AR71XX_DEV_LEDS_GPIO
  159. + select AR71XX_DEV_USB
  160. + default n
  161. +
  162. +config AR71XX_MACH_JWAP003
  163. + bool "jjPlus JWAP003 board support"
  164. + select SOC_AR71XX
  165. + select AR71XX_DEV_M25P80
  166. + select AR71XX_DEV_GPIO_BUTTONS
  167. + select AR71XX_DEV_PB42_PCI if PCI
  168. + select AR71XX_DEV_USB
  169. + default n
  170. +
  171. +config AR71XX_MACH_PB42
  172. + bool "Atheros PB42 board support"
  173. + select SOC_AR71XX
  174. + select AR71XX_DEV_M25P80
  175. + select AR71XX_DEV_GPIO_BUTTONS
  176. + select AR71XX_DEV_PB42_PCI if PCI
  177. + default n
  178. +
  179. +config AR71XX_MACH_PB44
  180. + bool "Atheros PB44 board support"
  181. + select SOC_AR71XX
  182. + select AR71XX_DEV_GPIO_BUTTONS
  183. + select AR71XX_DEV_PB42_PCI if PCI
  184. + select AR71XX_DEV_LEDS_GPIO
  185. + select AR71XX_DEV_USB
  186. + default n
  187. +
  188. +config AR71XX_MACH_PB92
  189. + bool "Atheros PB92 board support"
  190. + select SOC_AR724X
  191. + select AR71XX_DEV_GPIO_BUTTONS
  192. + select AR71XX_DEV_PB9X_PCI if PCI
  193. + select AR71XX_DEV_LEDS_GPIO
  194. + select AR71XX_DEV_USB
  195. + default n
  196. +
  197. +config AR71XX_MACH_AW_NR580
  198. + bool "AzureWave AW-NR580 board support"
  199. + select SOC_AR71XX
  200. + select AR71XX_DEV_M25P80
  201. + select AR71XX_DEV_GPIO_BUTTONS
  202. + select AR71XX_DEV_PB42_PCI if PCI
  203. + select AR71XX_DEV_LEDS_GPIO
  204. + default n
  205. +
  206. +config AR71XX_MACH_WZR_HP_AG300H
  207. + bool "Buffalo WZR-HP-AG300H board support"
  208. + select SOC_AR71XX
  209. + select AR71XX_DEV_M25P80
  210. + select AR71XX_DEV_GPIO_BUTTONS
  211. + select AR71XX_DEV_LEDS_GPIO
  212. + select AR71XX_DEV_USB
  213. + default n
  214. +
  215. +config AR71XX_MACH_WZR_HP_G300NH
  216. + bool "Buffalo WZR-HP-G300NH board support"
  217. + select SOC_AR913X
  218. + select AR71XX_DEV_AR9XXX_WMAC
  219. + select AR71XX_DEV_GPIO_BUTTONS
  220. + select AR71XX_DEV_LEDS_GPIO
  221. + select AR71XX_DEV_USB
  222. + select RTL8366_SMI
  223. + default n
  224. +
  225. +config AR71XX_MACH_WP543
  226. + bool "Compex WP543/WPJ543 board support"
  227. + select SOC_AR71XX
  228. + select MYLOADER
  229. + select AR71XX_DEV_M25P80
  230. + select AR71XX_DEV_GPIO_BUTTONS
  231. + select AR71XX_DEV_PB42_PCI if PCI
  232. + select AR71XX_DEV_LEDS_GPIO
  233. + select AR71XX_DEV_USB
  234. + default n
  235. +
  236. +config AR71XX_MACH_WRT160NL
  237. + bool "Linksys WRT160NL board support"
  238. + select SOC_AR913X
  239. + select AR71XX_DEV_M25P80
  240. + select AR71XX_DEV_AR9XXX_WMAC
  241. + select AR71XX_DEV_GPIO_BUTTONS
  242. + select AR71XX_DEV_LEDS_GPIO
  243. + select AR71XX_DEV_USB
  244. + select AR71XX_NVRAM
  245. + default n
  246. +
  247. +config AR71XX_MACH_WRT400N
  248. + bool "Linksys WRT400N board support"
  249. + select SOC_AR71XX
  250. + select AR71XX_DEV_AP94_PCI if PCI
  251. + select AR71XX_DEV_M25P80
  252. + select AR71XX_DEV_GPIO_BUTTONS
  253. + select AR71XX_DEV_LEDS_GPIO
  254. + default n
  255. +
  256. +config AR71XX_MACH_RB4XX
  257. + bool "MikroTik RouterBOARD 4xx series support"
  258. + select SOC_AR71XX
  259. + select AR71XX_DEV_GPIO_BUTTONS
  260. + select AR71XX_DEV_LEDS_GPIO
  261. + select AR71XX_DEV_USB
  262. + default n
  263. +
  264. +config AR71XX_MACH_RB750
  265. + bool "MikroTik RouterBOARD 750 support"
  266. + select SOC_AR724X
  267. + default n
  268. +
  269. +config AR71XX_MACH_WNDR3700
  270. + bool "NETGEAR WNDR3700 board support"
  271. + select SOC_AR71XX
  272. + select AR71XX_DEV_M25P80
  273. + select AR71XX_DEV_AP94_PCI if PCI
  274. + select AR71XX_DEV_GPIO_BUTTONS
  275. + select AR71XX_DEV_LEDS_GPIO
  276. + select AR71XX_DEV_USB
  277. + default n
  278. +
  279. +config AR71XX_MACH_WNR2000
  280. + bool "NETGEAR WNR2000 board support"
  281. + select SOC_AR913X
  282. + select AR71XX_DEV_M25P80
  283. + select AR71XX_DEV_AR9XXX_WMAC
  284. + select AR71XX_DEV_GPIO_BUTTONS
  285. + select AR71XX_DEV_LEDS_GPIO
  286. + default n
  287. +
  288. +config AR71XX_MACH_MZK_W04NU
  289. + bool "Planex MZK-W04NU board support"
  290. + select SOC_AR913X
  291. + select AR71XX_DEV_M25P80
  292. + select AR71XX_DEV_AR9XXX_WMAC
  293. + select AR71XX_DEV_GPIO_BUTTONS
  294. + select AR71XX_DEV_LEDS_GPIO
  295. + select AR71XX_DEV_USB
  296. + default n
  297. +
  298. +config AR71XX_MACH_MZK_W300NH
  299. + bool "Planex MZK-W300NH board support"
  300. + select SOC_AR913X
  301. + select AR71XX_DEV_M25P80
  302. + select AR71XX_DEV_AR9XXX_WMAC
  303. + select AR71XX_DEV_GPIO_BUTTONS
  304. + select AR71XX_DEV_LEDS_GPIO
  305. + default n
  306. +
  307. +config AR71XX_MACH_NBG460N
  308. + bool "Zyxel NBG460N/550N/550NH board support"
  309. + select SOC_AR913X
  310. + select AR71XX_DEV_M25P80
  311. + select AR71XX_DEV_AR9XXX_WMAC
  312. + select AR71XX_DEV_GPIO_BUTTONS
  313. + select AR71XX_DEV_LEDS_GPIO
  314. + default n
  315. +
  316. +config AR71XX_MACH_TL_MR3X20
  317. + bool "TP-LINK TL-MR3220/3420 support"
  318. + select SOC_AR724X
  319. + select AR71XX_DEV_M25P80
  320. + select AR71XX_DEV_AP91_PCI if PCI
  321. + select AR71XX_DEV_GPIO_BUTTONS
  322. + select AR71XX_DEV_LEDS_GPIO
  323. + select AR71XX_DEV_USB
  324. + default n
  325. +
  326. +config AR71XX_MACH_TL_WA901ND
  327. + bool "TP-LINK TL-WA901ND support"
  328. + select SOC_AR724X
  329. + select AR71XX_DEV_M25P80
  330. + select AR71XX_DEV_AP91_PCI if PCI
  331. + select AR71XX_DEV_GPIO_BUTTONS
  332. + select AR71XX_DEV_LEDS_GPIO
  333. + default n
  334. +
  335. +config AR71XX_MACH_TL_WA901ND_V2
  336. + bool "TP-LINK TL-WA901ND v2 support"
  337. + select SOC_AR913X
  338. + select AR71XX_DEV_M25P80
  339. + select AR71XX_DEV_AR9XXX_WMAC
  340. + select AR71XX_DEV_GPIO_BUTTONS
  341. + select AR71XX_DEV_LEDS_GPIO
  342. + default n
  343. +
  344. +config AR71XX_MACH_TL_WR741ND
  345. + bool "TP-LINK TL-WR741ND support"
  346. + select SOC_AR724X
  347. + select AR71XX_DEV_M25P80
  348. + select AR71XX_DEV_AP91_PCI if PCI
  349. + select AR71XX_DEV_GPIO_BUTTONS
  350. + select AR71XX_DEV_LEDS_GPIO
  351. + default n
  352. +
  353. +config AR71XX_MACH_TL_WR841N_V1
  354. + bool "TP-LINK TL-WR841N v1 support"
  355. + select SOC_AR71XX
  356. + select AR71XX_DEV_M25P80
  357. + select AR71XX_DEV_PB42_PCI if PCI
  358. + select AR71XX_DEV_DSA
  359. + select AR71XX_DEV_GPIO_BUTTONS
  360. + select AR71XX_DEV_LEDS_GPIO
  361. + default n
  362. +
  363. +config AR71XX_MACH_TL_WR941ND
  364. + bool "TP-LINK TL-WR941ND support"
  365. + select SOC_AR913X
  366. + select AR71XX_DEV_M25P80
  367. + select AR71XX_DEV_AR9XXX_WMAC
  368. + select AR71XX_DEV_DSA
  369. + select AR71XX_DEV_GPIO_BUTTONS
  370. + select AR71XX_DEV_LEDS_GPIO
  371. + default n
  372. +
  373. +config AR71XX_MACH_TL_WR1043ND
  374. + bool "TP-LINK TL-WR1043ND support"
  375. + select SOC_AR913X
  376. + select AR71XX_DEV_M25P80
  377. + select AR71XX_DEV_AR9XXX_WMAC
  378. + select AR71XX_DEV_GPIO_BUTTONS
  379. + select AR71XX_DEV_LEDS_GPIO
  380. + select AR71XX_DEV_USB
  381. + default n
  382. +
  383. +config AR71XX_MACH_TEW_632BRP
  384. + bool "TRENDnet TEW-632BRP support"
  385. + select SOC_AR913X
  386. + select AR71XX_DEV_M25P80
  387. + select AR71XX_DEV_AR9XXX_WMAC
  388. + select AR71XX_DEV_GPIO_BUTTONS
  389. + select AR71XX_DEV_LEDS_GPIO
  390. + select AR71XX_NVRAM
  391. + default n
  392. +
  393. +config AR71XX_MACH_UBNT
  394. + bool "Ubiquiti AR71xx based boards support"
  395. + select SOC_AR71XX
  396. + select SOC_AR724X
  397. + select AR71XX_DEV_M25P80
  398. + select AR71XX_DEV_AP91_PCI if PCI
  399. + select AR71XX_DEV_GPIO_BUTTONS
  400. + select AR71XX_DEV_LEDS_GPIO
  401. + select AR71XX_DEV_PB42_PCI if PCI
  402. + select AR71XX_DEV_USB
  403. + default n
  404. +
  405. +config AR71XX_MACH_EAP7660D
  406. + bool "Senao EAP7660D support"
  407. + select SOC_AR71XX
  408. + select AR71XX_DEV_M25P80
  409. + select AR71XX_DEV_GPIO_BUTTONS
  410. + select AR71XX_DEV_LEDS_GPIO
  411. + default n
  412. +
  413. +config AR71XX_MACH_ZCN_1523H
  414. + bool "Zcomax ZCN-1523H support"
  415. + select SOC_AR724X
  416. + select AR71XX_DEV_M25P80
  417. + select AR71XX_DEV_AP91_PCI if PCI
  418. + select AR71XX_DEV_GPIO_BUTTONS
  419. + select AR71XX_DEV_LEDS_GPIO
  420. + default n
  421. +
  422. +endmenu
  423. +
  424. +config SOC_AR71XX
  425. + bool
  426. + select USB_ARCH_HAS_EHCI
  427. + select USB_ARCH_HAS_OHCI
  428. +
  429. +config SOC_AR724X
  430. + bool
  431. + select USB_ARCH_HAS_EHCI
  432. + select USB_ARCH_HAS_OHCI
  433. +
  434. +config SOC_AR913X
  435. + bool
  436. + select USB_ARCH_HAS_EHCI
  437. +
  438. +config SOC_AR934X
  439. + bool
  440. + select USB_ARCH_HAS_EHCI
  441. +
  442. +config AR71XX_DEV_M25P80
  443. + def_bool n
  444. +
  445. +config AR71XX_DEV_AP91_PCI
  446. + select AR71XX_PCI_ATH9K_FIXUP
  447. + def_bool n
  448. +
  449. +config AR71XX_DEV_AP94_PCI
  450. + select AR71XX_PCI_ATH9K_FIXUP
  451. + def_bool n
  452. +
  453. +config AR71XX_DEV_AR9XXX_WMAC
  454. + def_bool n
  455. +
  456. +config AR71XX_DEV_DB120_PCI
  457. + select AR71XX_PCI_ATH9K_FIXUP
  458. + def_bool n
  459. +
  460. +config AR71XX_DEV_DSA
  461. + def_bool n
  462. +
  463. +config AR71XX_DEV_GPIO_BUTTONS
  464. + def_bool n
  465. +
  466. +config AR71XX_DEV_LEDS_GPIO
  467. + def_bool n
  468. +
  469. +config AR71XX_DEV_PB42_PCI
  470. + def_bool n
  471. +
  472. +config AR71XX_DEV_PB9X_PCI
  473. + def_bool n
  474. +
  475. +config AR71XX_DEV_USB
  476. + def_bool n
  477. +
  478. +config AR71XX_NVRAM
  479. + def_bool n
  480. +
  481. +config AR71XX_PCI_ATH9K_FIXUP
  482. + def_bool n
  483. +
  484. +config SOC_AR933X
  485. + bool
  486. + select USB_ARCH_HAS_EHCI
  487. +
  488. +endif
  489. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile
  490. --- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  491. +++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-08-24 18:17:23.000000000 +0200
  492. @@ -0,0 +1,67 @@
  493. +#
  494. +# Makefile for the Atheros AR71xx SoC specific parts of the kernel
  495. +#
  496. +# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  497. +# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  498. +#
  499. +# This program is free software; you can redistribute it and/or modify it
  500. +# under the terms of the GNU General Public License version 2 as published
  501. +# by the Free Software Foundation.
  502. +
  503. +obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o
  504. +
  505. +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  506. +obj-$(CONFIG_PCI) += pci.o
  507. +
  508. +obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o
  509. +obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o
  510. +obj-$(CONFIG_AR71XX_DEV_AR9XXX_WMAC) += dev-ar9xxx-wmac.o
  511. +obj-$(CONFIG_AR71XX_DEV_DB120_PCI) += dev-db120-pci.o
  512. +obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o
  513. +obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
  514. +obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o
  515. +obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o
  516. +obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o
  517. +obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o
  518. +obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o
  519. +
  520. +obj-$(CONFIG_AR71XX_NVRAM) += nvram.o
  521. +obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o
  522. +
  523. +obj-$(CONFIG_AR71XX_MACH_AP121) += mach-ap121.o
  524. +obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o
  525. +obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o
  526. +obj-$(CONFIG_AR71XX_MACH_AP96) += mach-ap96.o
  527. +obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o
  528. +obj-$(CONFIG_AR71XX_MACH_DB120) += mach-db120.o
  529. +obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o
  530. +obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o
  531. +obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o
  532. +obj-$(CONFIG_AR71XX_MACH_EAP7660D) += mach-eap7660d.o
  533. +obj-$(CONFIG_AR71XX_MACH_JA76PF) += mach-ja76pf.o
  534. +obj-$(CONFIG_AR71XX_MACH_JWAP003) += mach-jwap003.o
  535. +obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o
  536. +obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o
  537. +obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o
  538. +obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o
  539. +obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o
  540. +obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o
  541. +obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o
  542. +obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o
  543. +obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o
  544. +obj-$(CONFIG_AR71XX_MACH_TL_MR3X20) += mach-tl-mr3x20.o
  545. +obj-$(CONFIG_AR71XX_MACH_TL_WA901ND) += mach-tl-wa901nd.o
  546. +obj-$(CONFIG_AR71XX_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o
  547. +obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o
  548. +obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o
  549. +obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o
  550. +obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o
  551. +obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o
  552. +obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o
  553. +obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o
  554. +obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o
  555. +obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o
  556. +obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o
  557. +obj-$(CONFIG_AR71XX_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o
  558. +obj-$(CONFIG_AR71XX_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o
  559. +obj-$(CONFIG_AR71XX_MACH_ZCN_1523H) += mach-zcn-1523h.o
  560. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c
  561. --- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  562. +++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-08-24 18:17:23.000000000 +0200
  563. @@ -0,0 +1,230 @@
  564. +/*
  565. + * AR71xx SoC routines
  566. + *
  567. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  568. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  569. + *
  570. + * This program is free software; you can redistribute it and/or modify it
  571. + * under the terms of the GNU General Public License version 2 as published
  572. + * by the Free Software Foundation.
  573. + */
  574. +
  575. +#include <linux/kernel.h>
  576. +#include <linux/module.h>
  577. +#include <linux/types.h>
  578. +#include <linux/mutex.h>
  579. +#include <linux/spinlock.h>
  580. +
  581. +#include <asm/mach-ar71xx/ar71xx.h>
  582. +
  583. +static DEFINE_MUTEX(ar71xx_flash_mutex);
  584. +static DEFINE_SPINLOCK(ar71xx_device_lock);
  585. +
  586. +void __iomem *ar71xx_ddr_base;
  587. +EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
  588. +
  589. +void __iomem *ar71xx_pll_base;
  590. +EXPORT_SYMBOL_GPL(ar71xx_pll_base);
  591. +
  592. +void __iomem *ar71xx_reset_base;
  593. +EXPORT_SYMBOL_GPL(ar71xx_reset_base);
  594. +
  595. +void __iomem *ar71xx_gpio_base;
  596. +EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
  597. +
  598. +void __iomem *ar71xx_usb_ctrl_base;
  599. +EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
  600. +
  601. +void ar71xx_device_stop(u32 mask)
  602. +{
  603. + unsigned long flags;
  604. + u32 mask_inv;
  605. + u32 t;
  606. +
  607. + switch (ar71xx_soc) {
  608. + case AR71XX_SOC_AR7130:
  609. + case AR71XX_SOC_AR7141:
  610. + case AR71XX_SOC_AR7161:
  611. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  612. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  613. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
  614. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  615. + break;
  616. +
  617. + case AR71XX_SOC_AR7240:
  618. + case AR71XX_SOC_AR7241:
  619. + case AR71XX_SOC_AR7242:
  620. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  621. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  622. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  623. + t |= mask;
  624. + t &= ~mask_inv;
  625. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  626. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  627. + break;
  628. +
  629. + case AR71XX_SOC_AR9130:
  630. + case AR71XX_SOC_AR9132:
  631. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  632. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  633. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
  634. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  635. + break;
  636. +
  637. + case AR71XX_SOC_AR9330:
  638. + case AR71XX_SOC_AR9331:
  639. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  640. + t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE);
  641. + ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t | mask);
  642. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  643. + break;
  644. +
  645. + case AR71XX_SOC_AR9341:
  646. + case AR71XX_SOC_AR9342:
  647. + case AR71XX_SOC_AR9344:
  648. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  649. + t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE);
  650. + ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t | mask);
  651. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  652. + break;
  653. +
  654. + default:
  655. + BUG();
  656. + }
  657. +}
  658. +EXPORT_SYMBOL_GPL(ar71xx_device_stop);
  659. +
  660. +void ar71xx_device_start(u32 mask)
  661. +{
  662. + unsigned long flags;
  663. + u32 mask_inv;
  664. + u32 t;
  665. +
  666. + switch (ar71xx_soc) {
  667. + case AR71XX_SOC_AR7130:
  668. + case AR71XX_SOC_AR7141:
  669. + case AR71XX_SOC_AR7161:
  670. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  671. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  672. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
  673. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  674. + break;
  675. +
  676. + case AR71XX_SOC_AR7240:
  677. + case AR71XX_SOC_AR7241:
  678. + case AR71XX_SOC_AR7242:
  679. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  680. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  681. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  682. + t &= ~mask;
  683. + t |= mask_inv;
  684. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  685. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  686. + break;
  687. +
  688. + case AR71XX_SOC_AR9130:
  689. + case AR71XX_SOC_AR9132:
  690. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  691. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  692. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
  693. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  694. + break;
  695. +
  696. + case AR71XX_SOC_AR9330:
  697. + case AR71XX_SOC_AR9331:
  698. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  699. + t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE);
  700. + ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t & ~mask);
  701. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  702. + break;
  703. +
  704. + case AR71XX_SOC_AR9341:
  705. + case AR71XX_SOC_AR9342:
  706. + case AR71XX_SOC_AR9344:
  707. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  708. + t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE);
  709. + ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t & ~mask);
  710. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  711. + break;
  712. +
  713. + default:
  714. + BUG();
  715. + }
  716. +}
  717. +EXPORT_SYMBOL_GPL(ar71xx_device_start);
  718. +
  719. +int ar71xx_device_stopped(u32 mask)
  720. +{
  721. + unsigned long flags;
  722. + u32 t;
  723. +
  724. + switch (ar71xx_soc) {
  725. + case AR71XX_SOC_AR7130:
  726. + case AR71XX_SOC_AR7141:
  727. + case AR71XX_SOC_AR7161:
  728. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  729. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  730. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  731. + break;
  732. +
  733. + case AR71XX_SOC_AR7240:
  734. + case AR71XX_SOC_AR7241:
  735. + case AR71XX_SOC_AR7242:
  736. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  737. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  738. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  739. + break;
  740. +
  741. + case AR71XX_SOC_AR9130:
  742. + case AR71XX_SOC_AR9132:
  743. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  744. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  745. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  746. + break;
  747. +
  748. + case AR71XX_SOC_AR9330:
  749. + case AR71XX_SOC_AR9331:
  750. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  751. + t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE);
  752. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  753. + break;
  754. +
  755. + case AR71XX_SOC_AR9341:
  756. + case AR71XX_SOC_AR9342:
  757. + case AR71XX_SOC_AR9344:
  758. + spin_lock_irqsave(&ar71xx_device_lock, flags);
  759. + t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE);
  760. + spin_unlock_irqrestore(&ar71xx_device_lock, flags);
  761. + break;
  762. +
  763. + default:
  764. + BUG();
  765. + }
  766. +
  767. + return ((t & mask) == mask);
  768. +}
  769. +EXPORT_SYMBOL_GPL(ar71xx_device_stopped);
  770. +
  771. +void ar71xx_ddr_flush(u32 reg)
  772. +{
  773. + ar71xx_ddr_wr(reg, 1);
  774. + while ((ar71xx_ddr_rr(reg) & 0x1))
  775. + ;
  776. +
  777. + ar71xx_ddr_wr(reg, 1);
  778. + while ((ar71xx_ddr_rr(reg) & 0x1))
  779. + ;
  780. +}
  781. +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
  782. +
  783. +void ar71xx_flash_acquire(void)
  784. +{
  785. + mutex_lock(&ar71xx_flash_mutex);
  786. +}
  787. +EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
  788. +
  789. +void ar71xx_flash_release(void)
  790. +{
  791. + mutex_unlock(&ar71xx_flash_mutex);
  792. +}
  793. +EXPORT_SYMBOL_GPL(ar71xx_flash_release);
  794. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c
  795. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100
  796. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-08-24 18:17:23.000000000 +0200
  797. @@ -0,0 +1,71 @@
  798. +/*
  799. + * Atheros AP91 reference board PCI initialization
  800. + *
  801. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  802. + *
  803. + * This program is free software; you can redistribute it and/or modify it
  804. + * under the terms of the GNU General Public License version 2 as published
  805. + * by the Free Software Foundation.
  806. + */
  807. +
  808. +#include <linux/pci.h>
  809. +#include <linux/ath9k_platform.h>
  810. +#include <linux/delay.h>
  811. +
  812. +#include <asm/mach-ar71xx/ar71xx.h>
  813. +#include <asm/mach-ar71xx/pci.h>
  814. +
  815. +#include "dev-ap91-pci.h"
  816. +#include "pci-ath9k-fixup.h"
  817. +
  818. +static struct ath9k_platform_data ap91_wmac_data = {
  819. + .led_pin = -1,
  820. +};
  821. +static char ap91_wmac_mac[6];
  822. +
  823. +static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
  824. + {
  825. + .slot = 0,
  826. + .pin = 1,
  827. + .irq = AR71XX_PCI_IRQ_DEV0,
  828. + }
  829. +};
  830. +
  831. +static int ap91_pci_plat_dev_init(struct pci_dev *dev)
  832. +{
  833. + switch (PCI_SLOT(dev->devfn)) {
  834. + case 0:
  835. + dev->dev.platform_data = &ap91_wmac_data;
  836. + break;
  837. + }
  838. +
  839. + return 0;
  840. +}
  841. +
  842. +__init void ap91_pci_setup_wmac_led_pin(int pin)
  843. +{
  844. + ap91_wmac_data.led_pin = pin;
  845. +}
  846. +
  847. +__init void ap91_pci_setup_wmac_gpio(u32 mask, u32 val)
  848. +{
  849. + ap91_wmac_data.gpio_mask = mask;
  850. + ap91_wmac_data.gpio_val = val;
  851. +}
  852. +
  853. +void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
  854. +{
  855. + if (cal_data)
  856. + memcpy(ap91_wmac_data.eeprom_data, cal_data,
  857. + sizeof(ap91_wmac_data.eeprom_data));
  858. +
  859. + if (mac_addr) {
  860. + memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac));
  861. + ap91_wmac_data.macaddr = ap91_wmac_mac;
  862. + }
  863. +
  864. + ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
  865. + ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
  866. +
  867. + pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data);
  868. +}
  869. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h
  870. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100
  871. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-08-24 18:17:23.000000000 +0200
  872. @@ -0,0 +1,25 @@
  873. +/*
  874. + * Atheros AP91 reference board PCI initialization
  875. + *
  876. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  877. + *
  878. + * This program is free software; you can redistribute it and/or modify it
  879. + * under the terms of the GNU General Public License version 2 as published
  880. + * by the Free Software Foundation.
  881. + */
  882. +
  883. +#ifndef _AR71XX_DEV_AP91_PCI_H
  884. +#define _AR71XX_DEV_AP91_PCI_H
  885. +
  886. +#if defined(CONFIG_AR71XX_DEV_AP91_PCI)
  887. +void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init;
  888. +void ap91_pci_setup_wmac_led_pin(int pin) __init;
  889. +void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) __init;
  890. +#else
  891. +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { }
  892. +static inline void ap91_pci_setup_wmac_led_pin(int pin) { }
  893. +static inline void ap91_pci_setup_wmac_gpio(u32 mask, u32 gpio) { }
  894. +#endif
  895. +
  896. +#endif /* _AR71XX_DEV_AP91_PCI_H */
  897. +
  898. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c
  899. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100
  900. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-08-24 18:17:23.000000000 +0200
  901. @@ -0,0 +1,109 @@
  902. +/*
  903. + * Atheros AP94 reference board PCI initialization
  904. + *
  905. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  906. + *
  907. + * This program is free software; you can redistribute it and/or modify it
  908. + * under the terms of the GNU General Public License version 2 as published
  909. + * by the Free Software Foundation.
  910. + */
  911. +
  912. +#include <linux/pci.h>
  913. +#include <linux/ath9k_platform.h>
  914. +#include <linux/delay.h>
  915. +
  916. +#include <asm/mach-ar71xx/ar71xx.h>
  917. +#include <asm/mach-ar71xx/pci.h>
  918. +
  919. +#include "dev-ap94-pci.h"
  920. +#include "pci-ath9k-fixup.h"
  921. +
  922. +static struct ath9k_platform_data ap94_wmac0_data = {
  923. + .led_pin = -1,
  924. +};
  925. +static struct ath9k_platform_data ap94_wmac1_data = {
  926. + .led_pin = -1,
  927. +};
  928. +static char ap94_wmac0_mac[6];
  929. +static char ap94_wmac1_mac[6];
  930. +
  931. +static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
  932. + {
  933. + .slot = 0,
  934. + .pin = 1,
  935. + .irq = AR71XX_PCI_IRQ_DEV0,
  936. + }, {
  937. + .slot = 1,
  938. + .pin = 1,
  939. + .irq = AR71XX_PCI_IRQ_DEV1,
  940. + }
  941. +};
  942. +
  943. +static int ap94_pci_plat_dev_init(struct pci_dev *dev)
  944. +{
  945. + switch (PCI_SLOT(dev->devfn)) {
  946. + case 17:
  947. + dev->dev.platform_data = &ap94_wmac0_data;
  948. + break;
  949. +
  950. + case 18:
  951. + dev->dev.platform_data = &ap94_wmac1_data;
  952. + break;
  953. + }
  954. +
  955. + return 0;
  956. +}
  957. +
  958. +__init void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin)
  959. +{
  960. + switch (wmac) {
  961. + case 0:
  962. + ap94_wmac0_data.led_pin = pin;
  963. + break;
  964. + case 1:
  965. + ap94_wmac1_data.led_pin = pin;
  966. + break;
  967. + }
  968. +}
  969. +
  970. +__init void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val)
  971. +{
  972. + switch (wmac) {
  973. + case 0:
  974. + ap94_wmac0_data.gpio_mask = mask;
  975. + ap94_wmac0_data.gpio_val = val;
  976. + break;
  977. + case 1:
  978. + ap94_wmac1_data.gpio_mask = mask;
  979. + ap94_wmac1_data.gpio_val = val;
  980. + break;
  981. + }
  982. +}
  983. +
  984. +void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  985. + u8 *cal_data1, u8 *mac_addr1)
  986. +{
  987. + if (cal_data0)
  988. + memcpy(ap94_wmac0_data.eeprom_data, cal_data0,
  989. + sizeof(ap94_wmac0_data.eeprom_data));
  990. +
  991. + if (cal_data1)
  992. + memcpy(ap94_wmac1_data.eeprom_data, cal_data1,
  993. + sizeof(ap94_wmac1_data.eeprom_data));
  994. +
  995. + if (mac_addr0) {
  996. + memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac));
  997. + ap94_wmac0_data.macaddr = ap94_wmac0_mac;
  998. + }
  999. +
  1000. + if (mac_addr1) {
  1001. + memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac));
  1002. + ap94_wmac1_data.macaddr = ap94_wmac1_mac;
  1003. + }
  1004. +
  1005. + ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
  1006. + ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
  1007. +
  1008. + pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data);
  1009. + pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data);
  1010. +}
  1011. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h
  1012. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100
  1013. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-08-24 18:17:23.000000000 +0200
  1014. @@ -0,0 +1,31 @@
  1015. +/*
  1016. + * Atheros AP94 reference board PCI initialization
  1017. + *
  1018. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  1019. + *
  1020. + * This program is free software; you can redistribute it and/or modify it
  1021. + * under the terms of the GNU General Public License version 2 as published
  1022. + * by the Free Software Foundation.
  1023. + */
  1024. +
  1025. +#ifndef _AR71XX_DEV_AP94_PCI_H
  1026. +#define _AR71XX_DEV_AP94_PCI_H
  1027. +
  1028. +#if defined(CONFIG_AR71XX_DEV_AP94_PCI)
  1029. +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  1030. + u8 *cal_data1, u8 *mac_addr1) __init;
  1031. +
  1032. +void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) __init;
  1033. +void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) __init;
  1034. +
  1035. +#else
  1036. +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  1037. + u8 *cal_data1, u8 *mac_addr1) {}
  1038. +
  1039. +static inline void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) {}
  1040. +static inline void ap94_pci_setup_wmac_gpio(unsigned wmac,
  1041. + u32 mask, u32 val) {}
  1042. +#endif
  1043. +
  1044. +#endif /* _AR71XX_DEV_AP94_PCI_H */
  1045. +
  1046. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c
  1047. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c 1970-01-01 01:00:00.000000000 +0100
  1048. +++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c 2011-08-24 18:17:23.000000000 +0200
  1049. @@ -0,0 +1,154 @@
  1050. +/*
  1051. + * Atheros AR9XXX SoCs built-in WMAC device support
  1052. + *
  1053. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  1054. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1055. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1056. + *
  1057. + * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
  1058. + *
  1059. + * This program is free software; you can redistribute it and/or modify it
  1060. + * under the terms of the GNU General Public License version 2 as published
  1061. + * by the Free Software Foundation.
  1062. + */
  1063. +
  1064. +#include <linux/kernel.h>
  1065. +#include <linux/init.h>
  1066. +#include <linux/delay.h>
  1067. +#include <linux/etherdevice.h>
  1068. +#include <linux/platform_device.h>
  1069. +#include <linux/ath9k_platform.h>
  1070. +
  1071. +#include <asm/mach-ar71xx/ar71xx.h>
  1072. +
  1073. +#include "dev-ar9xxx-wmac.h"
  1074. +
  1075. +#define MHZ_25 (25 * 1000 * 1000)
  1076. +
  1077. +static struct ath9k_platform_data ar9xxx_wmac_data = {
  1078. + .led_pin = -1,
  1079. +};
  1080. +static char ar9xxx_wmac_mac[6];
  1081. +
  1082. +static struct resource ar9xxx_wmac_resources[] = {
  1083. + {
  1084. + /* .start and .end fields are filled dynamically */
  1085. + .flags = IORESOURCE_MEM,
  1086. + }, {
  1087. + .start = AR71XX_CPU_IRQ_IP2,
  1088. + .end = AR71XX_CPU_IRQ_IP2,
  1089. + .flags = IORESOURCE_IRQ,
  1090. + },
  1091. +};
  1092. +
  1093. +static struct platform_device ar9xxx_wmac_device = {
  1094. + .name = "ath9k",
  1095. + .id = -1,
  1096. + .resource = ar9xxx_wmac_resources,
  1097. + .num_resources = ARRAY_SIZE(ar9xxx_wmac_resources),
  1098. + .dev = {
  1099. + .platform_data = &ar9xxx_wmac_data,
  1100. + },
  1101. +};
  1102. +
  1103. +static void ar913x_wmac_init(void)
  1104. +{
  1105. + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
  1106. + mdelay(10);
  1107. +
  1108. + ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
  1109. + mdelay(10);
  1110. +
  1111. + ar9xxx_wmac_resources[0].start = AR91XX_WMAC_BASE;
  1112. + ar9xxx_wmac_resources[0].end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1;
  1113. +}
  1114. +
  1115. +static int ar933x_r1_get_wmac_revision(void)
  1116. +{
  1117. + return ar71xx_soc_rev;
  1118. +}
  1119. +
  1120. +static int ar933x_wmac_reset(void)
  1121. +{
  1122. + unsigned retries = 0;
  1123. +
  1124. + ar71xx_device_stop(AR933X_RESET_WMAC);
  1125. + ar71xx_device_start(AR933X_RESET_WMAC);
  1126. +
  1127. + while (1) {
  1128. + u32 bootstrap;
  1129. +
  1130. + bootstrap = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
  1131. + if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
  1132. + return 0;
  1133. +
  1134. + if (retries > 20)
  1135. + break;
  1136. +
  1137. + udelay(10000);
  1138. + retries++;
  1139. + }
  1140. +
  1141. + pr_err("ar93xx: WMAC reset timed out");
  1142. + return -ETIMEDOUT;
  1143. +}
  1144. +
  1145. +static void ar933x_wmac_init(void)
  1146. +{
  1147. + ar9xxx_wmac_device.name = "ar933x_wmac";
  1148. + ar9xxx_wmac_resources[0].start = AR933X_WMAC_BASE;
  1149. + ar9xxx_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
  1150. + if (ar71xx_ref_freq == MHZ_25)
  1151. + ar9xxx_wmac_data.is_clk_25mhz = true;
  1152. +
  1153. + if (ar71xx_soc_rev == 1)
  1154. + ar9xxx_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
  1155. +
  1156. + ar9xxx_wmac_data.external_reset = ar933x_wmac_reset;
  1157. +
  1158. + ar933x_wmac_reset();
  1159. +}
  1160. +
  1161. +static void ar934x_wmac_init(void)
  1162. +{
  1163. + ar9xxx_wmac_device.name = "ar934x_wmac";
  1164. + ar9xxx_wmac_resources[0].start = AR934X_WMAC_BASE;
  1165. + ar9xxx_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
  1166. + if (ar71xx_ref_freq == MHZ_25)
  1167. + ar9xxx_wmac_data.is_clk_25mhz = true;
  1168. +}
  1169. +
  1170. +void __init ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr)
  1171. +{
  1172. + switch (ar71xx_soc) {
  1173. + case AR71XX_SOC_AR9130:
  1174. + case AR71XX_SOC_AR9132:
  1175. + ar913x_wmac_init();
  1176. + break;
  1177. +
  1178. + case AR71XX_SOC_AR9330:
  1179. + case AR71XX_SOC_AR9331:
  1180. + ar933x_wmac_init();
  1181. + break;
  1182. +
  1183. + case AR71XX_SOC_AR9341:
  1184. + case AR71XX_SOC_AR9342:
  1185. + case AR71XX_SOC_AR9344:
  1186. + ar934x_wmac_init();
  1187. + break;
  1188. +
  1189. + default:
  1190. + BUG();
  1191. + }
  1192. +
  1193. + if (cal_data)
  1194. + memcpy(ar9xxx_wmac_data.eeprom_data, cal_data,
  1195. + sizeof(ar9xxx_wmac_data.eeprom_data));
  1196. +
  1197. + if (mac_addr) {
  1198. + memcpy(ar9xxx_wmac_mac, mac_addr, sizeof(ar9xxx_wmac_mac));
  1199. + ar9xxx_wmac_data.macaddr = ar9xxx_wmac_mac;
  1200. + }
  1201. +
  1202. + platform_device_register(&ar9xxx_wmac_device);
  1203. +}
  1204. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h
  1205. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h 1970-01-01 01:00:00.000000000 +0100
  1206. +++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h 2011-08-24 18:17:23.000000000 +0200
  1207. @@ -0,0 +1,20 @@
  1208. +/*
  1209. + * Atheros AR9XXX SoCs built-in WMAC device support
  1210. + *
  1211. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  1212. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1213. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1214. + *
  1215. + * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
  1216. + *
  1217. + * This program is free software; you can redistribute it and/or modify it
  1218. + * under the terms of the GNU General Public License version 2 as published
  1219. + * by the Free Software Foundation.
  1220. + */
  1221. +
  1222. +#ifndef _AR71XX_DEV_AR9XXX_WMAC_H
  1223. +#define _AR71XX_DEV_AR9XXX_WMAC_H
  1224. +
  1225. +void ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init;
  1226. +
  1227. +#endif /* _AR71XX_DEV_AR9XXX_WMAC_H */
  1228. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c
  1229. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c 1970-01-01 01:00:00.000000000 +0100
  1230. +++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c 2011-08-24 18:17:23.000000000 +0200
  1231. @@ -0,0 +1,31 @@
  1232. +/*
  1233. + * Atheros db120 reference board PCI initialization
  1234. + *
  1235. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  1236. + *
  1237. + * Parts of this file are based on Atheros linux 2.6.31 BSP
  1238. + *
  1239. + * This program is free software; you can redistribute it and/or modify it
  1240. + * under the terms of the GNU General Public License version 2 as published
  1241. + * by the Free Software Foundation.
  1242. + */
  1243. +
  1244. +#include <linux/pci.h>
  1245. +
  1246. +#include <asm/mach-ar71xx/ar71xx.h>
  1247. +#include <asm/mach-ar71xx/pci.h>
  1248. +
  1249. +#include "dev-db120-pci.h"
  1250. +
  1251. +static struct ar71xx_pci_irq db120_pci_irqs[] __initdata = {
  1252. + {
  1253. + .slot = 0,
  1254. + .pin = 1,
  1255. + .irq = AR71XX_PCI_IRQ_DEV0,
  1256. + }
  1257. +};
  1258. +
  1259. +void __init db120_pci_init(void)
  1260. +{
  1261. + ar71xx_pci_init(ARRAY_SIZE(db120_pci_irqs), db120_pci_irqs);
  1262. +}
  1263. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h
  1264. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h 1970-01-01 01:00:00.000000000 +0100
  1265. +++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h 2011-08-24 18:17:23.000000000 +0200
  1266. @@ -0,0 +1,22 @@
  1267. +/*
  1268. + * Atheros DB120 reference board PCI initialization
  1269. + *
  1270. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  1271. + *
  1272. + * Parts of this file are based on Atheros linux 2.6.31 BSP
  1273. + *
  1274. + * This program is free software; you can redistribute it and/or modify it
  1275. + * under the terms of the GNU General Public License version 2 as published
  1276. + * by the Free Software Foundation.
  1277. + */
  1278. +
  1279. +#ifndef _AR71XX_DEV_DB120_PCI_H
  1280. +#define _AR71XX_DEV_DB120_PCI_H
  1281. +
  1282. +#if defined(CONFIG_AR71XX_DEV_DB120_PCI)
  1283. +void db120_pci_init(void);
  1284. +#else
  1285. +static inline void db120_pci_init(void) { }
  1286. +#endif
  1287. +
  1288. +#endif /* _AR71XX_DEV_DB120_PCI_H */
  1289. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c
  1290. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100
  1291. +++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-08-24 18:17:23.000000000 +0200
  1292. @@ -0,0 +1,50 @@
  1293. +/*
  1294. + * Atheros AR71xx DSA switch device support
  1295. + *
  1296. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1297. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1298. + *
  1299. + * This program is free software; you can redistribute it and/or modify it
  1300. + * under the terms of the GNU General Public License version 2 as published
  1301. + * by the Free Software Foundation.
  1302. + */
  1303. +
  1304. +#include <linux/init.h>
  1305. +#include <linux/platform_device.h>
  1306. +
  1307. +#include <asm/mach-ar71xx/ar71xx.h>
  1308. +
  1309. +#include "devices.h"
  1310. +#include "dev-dsa.h"
  1311. +
  1312. +static struct platform_device ar71xx_dsa_switch_device = {
  1313. + .name = "dsa",
  1314. + .id = 0,
  1315. +};
  1316. +
  1317. +void __init ar71xx_add_device_dsa(unsigned int id,
  1318. + struct dsa_platform_data *d)
  1319. +{
  1320. + int i;
  1321. +
  1322. + switch (id) {
  1323. + case 0:
  1324. + d->netdev = &ar71xx_eth0_device.dev;
  1325. + break;
  1326. + case 1:
  1327. + d->netdev = &ar71xx_eth1_device.dev;
  1328. + break;
  1329. + default:
  1330. + printk(KERN_ERR
  1331. + "ar71xx: invalid ethernet id %d for DSA switch\n",
  1332. + id);
  1333. + return;
  1334. + }
  1335. +
  1336. + for (i = 0; i < d->nr_chips; i++)
  1337. + d->chip[i].mii_bus = &ar71xx_mdio_device.dev;
  1338. +
  1339. + ar71xx_dsa_switch_device.dev.platform_data = d;
  1340. +
  1341. + platform_device_register(&ar71xx_dsa_switch_device);
  1342. +}
  1343. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar71xx/dev-dsa.h
  1344. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100
  1345. +++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-08-24 18:17:23.000000000 +0200
  1346. @@ -0,0 +1,20 @@
  1347. +/*
  1348. + * Atheros AR71xx DSA switch device support
  1349. + *
  1350. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1351. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1352. + *
  1353. + * This program is free software; you can redistribute it and/or modify it
  1354. + * under the terms of the GNU General Public License version 2 as published
  1355. + * by the Free Software Foundation.
  1356. + */
  1357. +
  1358. +#ifndef _AR71XX_DEV_DSA_H
  1359. +#define _AR71XX_DEV_DSA_H
  1360. +
  1361. +#include <net/dsa.h>
  1362. +
  1363. +void ar71xx_add_device_dsa(unsigned int id,
  1364. + struct dsa_platform_data *d) __init;
  1365. +
  1366. +#endif /* _AR71XX_DEV_DSA_H */
  1367. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c
  1368. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100
  1369. +++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-08-24 18:17:23.000000000 +0200
  1370. @@ -0,0 +1,58 @@
  1371. +/*
  1372. + * Atheros AR71xx GPIO button support
  1373. + *
  1374. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1375. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1376. + *
  1377. + * This program is free software; you can redistribute it and/or modify it
  1378. + * under the terms of the GNU General Public License version 2 as published
  1379. + * by the Free Software Foundation.
  1380. + */
  1381. +
  1382. +#include "linux/init.h"
  1383. +#include "linux/slab.h"
  1384. +#include <linux/platform_device.h>
  1385. +
  1386. +#include "dev-gpio-buttons.h"
  1387. +
  1388. +void __init ar71xx_register_gpio_keys_polled(int id,
  1389. + unsigned poll_interval,
  1390. + unsigned nbuttons,
  1391. + struct gpio_keys_button *buttons)
  1392. +{
  1393. + struct platform_device *pdev;
  1394. + struct gpio_keys_platform_data pdata;
  1395. + struct gpio_keys_button *p;
  1396. + int err;
  1397. +
  1398. + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
  1399. + if (!p)
  1400. + return;
  1401. +
  1402. + memcpy(p, buttons, nbuttons * sizeof(*p));
  1403. +
  1404. + pdev = platform_device_alloc("gpio-keys-polled", id);
  1405. + if (!pdev)
  1406. + goto err_free_buttons;
  1407. +
  1408. + memset(&pdata, 0, sizeof(pdata));
  1409. + pdata.poll_interval = poll_interval;
  1410. + pdata.nbuttons = nbuttons;
  1411. + pdata.buttons = p;
  1412. +
  1413. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1414. + if (err)
  1415. + goto err_put_pdev;
  1416. +
  1417. + err = platform_device_add(pdev);
  1418. + if (err)
  1419. + goto err_put_pdev;
  1420. +
  1421. + return;
  1422. +
  1423. +err_put_pdev:
  1424. + platform_device_put(pdev);
  1425. +
  1426. +err_free_buttons:
  1427. + kfree(p);
  1428. +}
  1429. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h
  1430. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100
  1431. +++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-08-24 18:17:23.000000000 +0200
  1432. @@ -0,0 +1,23 @@
  1433. +/*
  1434. + * Atheros AR71xx GPIO button support
  1435. + *
  1436. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1437. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1438. + *
  1439. + * This program is free software; you can redistribute it and/or modify it
  1440. + * under the terms of the GNU General Public License version 2 as published
  1441. + * by the Free Software Foundation.
  1442. + */
  1443. +
  1444. +#ifndef _AR71XX_DEV_GPIO_BUTTONS_H
  1445. +#define _AR71XX_DEV_GPIO_BUTTONS_H
  1446. +
  1447. +#include <linux/input.h>
  1448. +#include <linux/gpio_keys.h>
  1449. +
  1450. +void ar71xx_register_gpio_keys_polled(int id,
  1451. + unsigned poll_interval,
  1452. + unsigned nbuttons,
  1453. + struct gpio_keys_button *buttons);
  1454. +
  1455. +#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */
  1456. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c
  1457. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100
  1458. +++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-08-24 18:17:23.000000000 +0200
  1459. @@ -0,0 +1,57 @@
  1460. +/*
  1461. + * Atheros AR71xx GPIO LED device support
  1462. + *
  1463. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1464. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1465. + *
  1466. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1467. + *
  1468. + * This program is free software; you can redistribute it and/or modify it
  1469. + * under the terms of the GNU General Public License version 2 as published
  1470. + * by the Free Software Foundation.
  1471. + */
  1472. +
  1473. +#include <linux/init.h>
  1474. +#include <linux/slab.h>
  1475. +#include <linux/platform_device.h>
  1476. +
  1477. +#include "dev-leds-gpio.h"
  1478. +
  1479. +void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
  1480. + struct gpio_led *leds)
  1481. +{
  1482. + struct platform_device *pdev;
  1483. + struct gpio_led_platform_data pdata;
  1484. + struct gpio_led *p;
  1485. + int err;
  1486. +
  1487. + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
  1488. + if (!p)
  1489. + return;
  1490. +
  1491. + memcpy(p, leds, num_leds * sizeof(*p));
  1492. +
  1493. + pdev = platform_device_alloc("leds-gpio", id);
  1494. + if (!pdev)
  1495. + goto err_free_leds;
  1496. +
  1497. + memset(&pdata, 0, sizeof(pdata));
  1498. + pdata.num_leds = num_leds;
  1499. + pdata.leds = p;
  1500. +
  1501. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1502. + if (err)
  1503. + goto err_put_pdev;
  1504. +
  1505. + err = platform_device_add(pdev);
  1506. + if (err)
  1507. + goto err_put_pdev;
  1508. +
  1509. + return;
  1510. +
  1511. +err_put_pdev:
  1512. + platform_device_put(pdev);
  1513. +
  1514. +err_free_leds:
  1515. + kfree(p);
  1516. +}
  1517. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h
  1518. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100
  1519. +++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-08-24 18:17:23.000000000 +0200
  1520. @@ -0,0 +1,21 @@
  1521. +/*
  1522. + * Atheros AR71xx GPIO LED device support
  1523. + *
  1524. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1525. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1526. + *
  1527. + * This program is free software; you can redistribute it and/or modify it
  1528. + * under the terms of the GNU General Public License version 2 as published
  1529. + * by the Free Software Foundation.
  1530. + */
  1531. +
  1532. +#ifndef _AR71XX_DEV_LEDS_GPIO_H
  1533. +#define _AR71XX_DEV_LEDS_GPIO_H
  1534. +
  1535. +#include <linux/leds.h>
  1536. +
  1537. +void ar71xx_add_device_leds_gpio(int id,
  1538. + unsigned num_leds,
  1539. + struct gpio_led *leds) __init;
  1540. +
  1541. +#endif /* _AR71XX_DEV_LEDS_GPIO_H */
  1542. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c
  1543. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100
  1544. +++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-08-24 18:17:23.000000000 +0200
  1545. @@ -0,0 +1,30 @@
  1546. +/*
  1547. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1548. + *
  1549. + * This program is free software; you can redistribute it and/or modify it
  1550. + * under the terms of the GNU General Public License version 2 as published
  1551. + * by the Free Software Foundation.
  1552. + */
  1553. +
  1554. +#include <linux/init.h>
  1555. +#include <linux/spi/spi.h>
  1556. +#include <linux/spi/flash.h>
  1557. +
  1558. +#include "devices.h"
  1559. +#include "dev-m25p80.h"
  1560. +
  1561. +static struct spi_board_info ar71xx_spi_info[] = {
  1562. + {
  1563. + .bus_num = 0,
  1564. + .chip_select = 0,
  1565. + .max_speed_hz = 25000000,
  1566. + .modalias = "m25p80",
  1567. + }
  1568. +};
  1569. +
  1570. +void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata)
  1571. +{
  1572. + ar71xx_spi_info[0].platform_data = pdata;
  1573. + ar71xx_add_device_spi(NULL, ar71xx_spi_info,
  1574. + ARRAY_SIZE(ar71xx_spi_info));
  1575. +}
  1576. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h
  1577. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100
  1578. +++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-08-24 18:17:23.000000000 +0200
  1579. @@ -0,0 +1,16 @@
  1580. +/*
  1581. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1582. + *
  1583. + * This program is free software; you can redistribute it and/or modify it
  1584. + * under the terms of the GNU General Public License version 2 as published
  1585. + * by the Free Software Foundation.
  1586. + */
  1587. +
  1588. +#ifndef _AR71XX_DEV_M25P80_H
  1589. +#define _AR71XX_DEV_M25P80_H
  1590. +
  1591. +#include <linux/spi/flash.h>
  1592. +
  1593. +void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init;
  1594. +
  1595. +#endif /* _AR71XX_DEV_M25P80_H */
  1596. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c
  1597. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100
  1598. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-08-24 18:17:23.000000000 +0200
  1599. @@ -0,0 +1,40 @@
  1600. +/*
  1601. + * Atheros PB42 reference board PCI initialization
  1602. + *
  1603. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1604. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1605. + *
  1606. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1607. + *
  1608. + * This program is free software; you can redistribute it and/or modify it
  1609. + * under the terms of the GNU General Public License version 2 as published
  1610. + * by the Free Software Foundation.
  1611. + */
  1612. +
  1613. +#include <linux/pci.h>
  1614. +
  1615. +#include <asm/mach-ar71xx/ar71xx.h>
  1616. +#include <asm/mach-ar71xx/pci.h>
  1617. +
  1618. +#include "dev-pb42-pci.h"
  1619. +
  1620. +static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
  1621. + {
  1622. + .slot = 0,
  1623. + .pin = 1,
  1624. + .irq = AR71XX_PCI_IRQ_DEV0,
  1625. + }, {
  1626. + .slot = 1,
  1627. + .pin = 1,
  1628. + .irq = AR71XX_PCI_IRQ_DEV1,
  1629. + }, {
  1630. + .slot = 2,
  1631. + .pin = 1,
  1632. + .irq = AR71XX_PCI_IRQ_DEV2,
  1633. + }
  1634. +};
  1635. +
  1636. +void __init pb42_pci_init(void)
  1637. +{
  1638. + ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
  1639. +}
  1640. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h
  1641. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100
  1642. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-08-24 18:17:23.000000000 +0200
  1643. @@ -0,0 +1,21 @@
  1644. +/*
  1645. + * Atheros PB42 reference board PCI initialization
  1646. + *
  1647. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1648. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1649. + *
  1650. + * This program is free software; you can redistribute it and/or modify it
  1651. + * under the terms of the GNU General Public License version 2 as published
  1652. + * by the Free Software Foundation.
  1653. + */
  1654. +
  1655. +#ifndef _AR71XX_DEV_PB42_PCI_H
  1656. +#define _AR71XX_DEV_PB42_PCI_H
  1657. +
  1658. +#if defined(CONFIG_AR71XX_DEV_PB42_PCI)
  1659. +void pb42_pci_init(void) __init;
  1660. +#else
  1661. +static inline void pb42_pci_init(void) { }
  1662. +#endif
  1663. +
  1664. +#endif /* _AR71XX_DEV_PB42_PCI_H */
  1665. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c
  1666. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100
  1667. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-08-24 18:17:23.000000000 +0200
  1668. @@ -0,0 +1,33 @@
  1669. +/*
  1670. + * Atheros PB9x reference board PCI initialization
  1671. + *
  1672. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1673. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1674. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1675. + *
  1676. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1677. + *
  1678. + * This program is free software; you can redistribute it and/or modify it
  1679. + * under the terms of the GNU General Public License version 2 as published
  1680. + * by the Free Software Foundation.
  1681. + */
  1682. +
  1683. +#include <linux/pci.h>
  1684. +
  1685. +#include <asm/mach-ar71xx/ar71xx.h>
  1686. +#include <asm/mach-ar71xx/pci.h>
  1687. +
  1688. +#include "dev-pb9x-pci.h"
  1689. +
  1690. +static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = {
  1691. + {
  1692. + .slot = 0,
  1693. + .pin = 1,
  1694. + .irq = AR71XX_PCI_IRQ_DEV0,
  1695. + }
  1696. +};
  1697. +
  1698. +void __init pb9x_pci_init(void)
  1699. +{
  1700. + ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs);
  1701. +}
  1702. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h
  1703. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100
  1704. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-08-24 18:17:23.000000000 +0200
  1705. @@ -0,0 +1,22 @@
  1706. +/*
  1707. + * Atheros PB9x reference board PCI initialization
  1708. + *
  1709. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1710. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1711. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1712. + *
  1713. + * This program is free software; you can redistribute it and/or modify it
  1714. + * under the terms of the GNU General Public License version 2 as published
  1715. + * by the Free Software Foundation.
  1716. + */
  1717. +
  1718. +#ifndef _AR71XX_DEV_PB9X_PCI_H
  1719. +#define _AR71XX_DEV_PB9X_PCI_H
  1720. +
  1721. +#if defined(CONFIG_AR71XX_DEV_PB9X_PCI)
  1722. +void pb9x_pci_init(void) __init;
  1723. +#else
  1724. +static inline void pb9x_pci_init(void) { }
  1725. +#endif
  1726. +
  1727. +#endif /* _AR71XX_DEV_PB9X_PCI_H */
  1728. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c
  1729. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100
  1730. +++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-08-24 18:17:23.000000000 +0200
  1731. @@ -0,0 +1,199 @@
  1732. +/*
  1733. + * Atheros AR71xx USB host device support
  1734. + *
  1735. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1736. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1737. + *
  1738. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1739. + *
  1740. + * This program is free software; you can redistribute it and/or modify it
  1741. + * under the terms of the GNU General Public License version 2 as published
  1742. + * by the Free Software Foundation.
  1743. + */
  1744. +
  1745. +#include <linux/kernel.h>
  1746. +#include <linux/init.h>
  1747. +#include <linux/delay.h>
  1748. +#include <linux/dma-mapping.h>
  1749. +#include <linux/platform_device.h>
  1750. +
  1751. +#include <asm/mach-ar71xx/ar71xx.h>
  1752. +#include <asm/mach-ar71xx/platform.h>
  1753. +
  1754. +#include "dev-usb.h"
  1755. +
  1756. +/*
  1757. + * OHCI (USB full speed host controller)
  1758. + */
  1759. +static struct resource ar71xx_ohci_resources[] = {
  1760. + [0] = {
  1761. + .start = AR71XX_OHCI_BASE,
  1762. + .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
  1763. + .flags = IORESOURCE_MEM,
  1764. + },
  1765. + [1] = {
  1766. + .start = AR71XX_MISC_IRQ_OHCI,
  1767. + .end = AR71XX_MISC_IRQ_OHCI,
  1768. + .flags = IORESOURCE_IRQ,
  1769. + },
  1770. +};
  1771. +
  1772. +static struct resource ar7240_ohci_resources[] = {
  1773. + [0] = {
  1774. + .start = AR7240_OHCI_BASE,
  1775. + .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
  1776. + .flags = IORESOURCE_MEM,
  1777. + },
  1778. + [1] = {
  1779. + .start = AR71XX_CPU_IRQ_USB,
  1780. + .end = AR71XX_CPU_IRQ_USB,
  1781. + .flags = IORESOURCE_IRQ,
  1782. + },
  1783. +};
  1784. +
  1785. +static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
  1786. +static struct platform_device ar71xx_ohci_device = {
  1787. + .name = "ar71xx-ohci",
  1788. + .id = -1,
  1789. + .resource = ar71xx_ohci_resources,
  1790. + .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
  1791. + .dev = {
  1792. + .dma_mask = &ar71xx_ohci_dmamask,
  1793. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1794. + },
  1795. +};
  1796. +
  1797. +/*
  1798. + * EHCI (USB high/full speed host controller)
  1799. + */
  1800. +static struct resource ar71xx_ehci_resources[] = {
  1801. + [0] = {
  1802. + .start = AR71XX_EHCI_BASE,
  1803. + .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
  1804. + .flags = IORESOURCE_MEM,
  1805. + },
  1806. + [1] = {
  1807. + .start = AR71XX_CPU_IRQ_USB,
  1808. + .end = AR71XX_CPU_IRQ_USB,
  1809. + .flags = IORESOURCE_IRQ,
  1810. + },
  1811. +};
  1812. +
  1813. +static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
  1814. +static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
  1815. +
  1816. +static struct platform_device ar71xx_ehci_device = {
  1817. + .name = "ar71xx-ehci",
  1818. + .id = -1,
  1819. + .resource = ar71xx_ehci_resources,
  1820. + .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
  1821. + .dev = {
  1822. + .dma_mask = &ar71xx_ehci_dmamask,
  1823. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1824. + .platform_data = &ar71xx_ehci_data,
  1825. + },
  1826. +};
  1827. +
  1828. +#define AR71XX_USB_RESET_MASK \
  1829. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
  1830. + | RESET_MODULE_USB_OHCI_DLL)
  1831. +
  1832. +#define AR7240_USB_RESET_MASK \
  1833. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
  1834. +
  1835. +static void __init ar71xx_usb_setup(void)
  1836. +{
  1837. + ar71xx_device_stop(AR71XX_USB_RESET_MASK);
  1838. + mdelay(1000);
  1839. + ar71xx_device_start(AR71XX_USB_RESET_MASK);
  1840. +
  1841. + /* Turning on the Buff and Desc swap bits */
  1842. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
  1843. +
  1844. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1845. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
  1846. +
  1847. + mdelay(900);
  1848. +
  1849. + platform_device_register(&ar71xx_ohci_device);
  1850. + platform_device_register(&ar71xx_ehci_device);
  1851. +}
  1852. +
  1853. +static void __init ar7240_usb_setup(void)
  1854. +{
  1855. + ar71xx_device_stop(AR7240_USB_RESET_MASK);
  1856. + mdelay(1000);
  1857. + ar71xx_device_start(AR7240_USB_RESET_MASK);
  1858. +
  1859. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1860. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
  1861. +
  1862. + ar71xx_ohci_device.resource = ar7240_ohci_resources;
  1863. + ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1864. + platform_device_register(&ar71xx_ohci_device);
  1865. +}
  1866. +
  1867. +static void __init ar7241_usb_setup(void)
  1868. +{
  1869. + ar71xx_device_start(AR724X_RESET_USBSUS_OVERRIDE);
  1870. + mdelay(10);
  1871. +
  1872. + ar71xx_device_start(AR724X_RESET_USB_HOST);
  1873. + mdelay(10);
  1874. +
  1875. + ar71xx_device_start(AR724X_RESET_USB_PHY);
  1876. + mdelay(10);
  1877. +
  1878. + ar71xx_ehci_data.is_ar91xx = 1;
  1879. + ar71xx_ehci_device.resource = ar7240_ohci_resources;
  1880. + ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1881. + platform_device_register(&ar71xx_ehci_device);
  1882. +}
  1883. +
  1884. +static void __init ar91xx_usb_setup(void)
  1885. +{
  1886. + ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
  1887. + mdelay(10);
  1888. +
  1889. + ar71xx_device_start(RESET_MODULE_USB_HOST);
  1890. + mdelay(10);
  1891. +
  1892. + ar71xx_device_start(RESET_MODULE_USB_PHY);
  1893. + mdelay(10);
  1894. +
  1895. + ar71xx_ehci_data.is_ar91xx = 1;
  1896. + platform_device_register(&ar71xx_ehci_device);
  1897. +}
  1898. +
  1899. +void __init ar71xx_add_device_usb(void)
  1900. +{
  1901. + switch (ar71xx_soc) {
  1902. + case AR71XX_SOC_AR7240:
  1903. + ar7240_usb_setup();
  1904. + break;
  1905. +
  1906. + case AR71XX_SOC_AR7241:
  1907. + case AR71XX_SOC_AR7242:
  1908. + ar7241_usb_setup();
  1909. + break;
  1910. +
  1911. + case AR71XX_SOC_AR7130:
  1912. + case AR71XX_SOC_AR7141:
  1913. + case AR71XX_SOC_AR7161:
  1914. + ar71xx_usb_setup();
  1915. + break;
  1916. +
  1917. + case AR71XX_SOC_AR9130:
  1918. + case AR71XX_SOC_AR9132:
  1919. + case AR71XX_SOC_AR9330:
  1920. + case AR71XX_SOC_AR9331:
  1921. + case AR71XX_SOC_AR9341:
  1922. + case AR71XX_SOC_AR9342:
  1923. + case AR71XX_SOC_AR9344:
  1924. + ar91xx_usb_setup();
  1925. + break;
  1926. +
  1927. + default:
  1928. + BUG();
  1929. + }
  1930. +}
  1931. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar71xx/dev-usb.h
  1932. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100
  1933. +++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-08-24 18:17:23.000000000 +0200
  1934. @@ -0,0 +1,17 @@
  1935. +/*
  1936. + * Atheros AR71xx USB host device support
  1937. + *
  1938. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1939. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1940. + *
  1941. + * This program is free software; you can redistribute it and/or modify it
  1942. + * under the terms of the GNU General Public License version 2 as published
  1943. + * by the Free Software Foundation.
  1944. + */
  1945. +
  1946. +#ifndef _AR71XX_DEV_USB_H
  1947. +#define _AR71XX_DEV_USB_H
  1948. +
  1949. +void ar71xx_add_device_usb(void) __init;
  1950. +
  1951. +#endif /* _AR71XX_DEV_USB_H */
  1952. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c
  1953. --- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100
  1954. +++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-08-24 18:17:23.000000000 +0200
  1955. @@ -0,0 +1,765 @@
  1956. +/*
  1957. + * Atheros AR71xx SoC platform devices
  1958. + *
  1959. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  1960. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1961. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1962. + *
  1963. + * Parts of this file are based on Atheros 2.6.15 BSP
  1964. + * Parts of this file are based on Atheros 2.6.31 BSP
  1965. + *
  1966. + * This program is free software; you can redistribute it and/or modify it
  1967. + * under the terms of the GNU General Public License version 2 as published
  1968. + * by the Free Software Foundation.
  1969. + */
  1970. +
  1971. +#include <linux/kernel.h>
  1972. +#include <linux/init.h>
  1973. +#include <linux/delay.h>
  1974. +#include <linux/etherdevice.h>
  1975. +#include <linux/platform_device.h>
  1976. +#include <linux/serial_8250.h>
  1977. +
  1978. +#include <asm/mach-ar71xx/ar71xx.h>
  1979. +#include <asm/mach-ar71xx/ar933x_uart_platform.h>
  1980. +
  1981. +#include "devices.h"
  1982. +
  1983. +unsigned char ar71xx_mac_base[ETH_ALEN] __initdata;
  1984. +
  1985. +static struct resource ar71xx_uart_resources[] = {
  1986. + {
  1987. + .start = AR71XX_UART_BASE,
  1988. + .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
  1989. + .flags = IORESOURCE_MEM,
  1990. + },
  1991. +};
  1992. +
  1993. +#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
  1994. +static struct plat_serial8250_port ar71xx_uart_data[] = {
  1995. + {
  1996. + .mapbase = AR71XX_UART_BASE,
  1997. + .irq = AR71XX_MISC_IRQ_UART,
  1998. + .flags = AR71XX_UART_FLAGS,
  1999. + .iotype = UPIO_MEM32,
  2000. + .regshift = 2,
  2001. + }, {
  2002. + /* terminating entry */
  2003. + }
  2004. +};
  2005. +
  2006. +static struct platform_device ar71xx_uart_device = {
  2007. + .name = "serial8250",
  2008. + .id = PLAT8250_DEV_PLATFORM,
  2009. + .resource = ar71xx_uart_resources,
  2010. + .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
  2011. + .dev = {
  2012. + .platform_data = ar71xx_uart_data
  2013. + },
  2014. +};
  2015. +
  2016. +static struct resource ar933x_uart_resources[] = {
  2017. + {
  2018. + .start = AR933X_UART_BASE,
  2019. + .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
  2020. + .flags = IORESOURCE_MEM,
  2021. + },
  2022. + {
  2023. + .start = AR71XX_MISC_IRQ_UART,
  2024. + .end = AR71XX_MISC_IRQ_UART,
  2025. + .flags = IORESOURCE_IRQ,
  2026. + },
  2027. +};
  2028. +
  2029. +static struct ar933x_uart_platform_data ar933x_uart_data;
  2030. +static struct platform_device ar933x_uart_device = {
  2031. + .name = "ar933x-uart",
  2032. + .id = -1,
  2033. + .resource = ar933x_uart_resources,
  2034. + .num_resources = ARRAY_SIZE(ar933x_uart_resources),
  2035. + .dev = {
  2036. + .platform_data = &ar933x_uart_data,
  2037. + },
  2038. +};
  2039. +
  2040. +void __init ar71xx_add_device_uart(void)
  2041. +{
  2042. + struct platform_device *pdev;
  2043. +
  2044. + switch (ar71xx_soc) {
  2045. + case AR71XX_SOC_AR7130:
  2046. + case AR71XX_SOC_AR7141:
  2047. + case AR71XX_SOC_AR7161:
  2048. + case AR71XX_SOC_AR7240:
  2049. + case AR71XX_SOC_AR7241:
  2050. + case AR71XX_SOC_AR7242:
  2051. + case AR71XX_SOC_AR9130:
  2052. + case AR71XX_SOC_AR9132:
  2053. + pdev = &ar71xx_uart_device;
  2054. + ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
  2055. + break;
  2056. +
  2057. + case AR71XX_SOC_AR9330:
  2058. + case AR71XX_SOC_AR9331:
  2059. + pdev = &ar933x_uart_device;
  2060. + ar933x_uart_data.uartclk = ar71xx_ref_freq;
  2061. + break;
  2062. +
  2063. + case AR71XX_SOC_AR9341:
  2064. + case AR71XX_SOC_AR9342:
  2065. + case AR71XX_SOC_AR9344:
  2066. + pdev = &ar71xx_uart_device;
  2067. + ar71xx_uart_data[0].uartclk = ar71xx_ref_freq;
  2068. + break;
  2069. +
  2070. + default:
  2071. + BUG();
  2072. + }
  2073. +
  2074. + platform_device_register(pdev);
  2075. +}
  2076. +
  2077. +static struct resource ar71xx_mdio_resources[] = {
  2078. + {
  2079. + .name = "mdio_base",
  2080. + .flags = IORESOURCE_MEM,
  2081. + .start = AR71XX_GE0_BASE,
  2082. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  2083. + }
  2084. +};
  2085. +
  2086. +static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
  2087. +
  2088. +struct platform_device ar71xx_mdio_device = {
  2089. + .name = "ag71xx-mdio",
  2090. + .id = -1,
  2091. + .resource = ar71xx_mdio_resources,
  2092. + .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
  2093. + .dev = {
  2094. + .platform_data = &ar71xx_mdio_data,
  2095. + },
  2096. +};
  2097. +
  2098. +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
  2099. +{
  2100. + void __iomem *base;
  2101. + u32 t;
  2102. +
  2103. + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
  2104. +
  2105. + t = __raw_readl(base + cfg_reg);
  2106. + t &= ~(3 << shift);
  2107. + t |= (2 << shift);
  2108. + __raw_writel(t, base + cfg_reg);
  2109. + udelay(100);
  2110. +
  2111. + __raw_writel(pll_val, base + pll_reg);
  2112. +
  2113. + t |= (3 << shift);
  2114. + __raw_writel(t, base + cfg_reg);
  2115. + udelay(100);
  2116. +
  2117. + t &= ~(3 << shift);
  2118. + __raw_writel(t, base + cfg_reg);
  2119. + udelay(100);
  2120. +
  2121. + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
  2122. + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
  2123. +
  2124. + iounmap(base);
  2125. +}
  2126. +
  2127. +void __init ar71xx_add_device_mdio(u32 phy_mask)
  2128. +{
  2129. + switch (ar71xx_soc) {
  2130. + case AR71XX_SOC_AR7240:
  2131. + ar71xx_mdio_data.is_ar7240 = 1;
  2132. + break;
  2133. + case AR71XX_SOC_AR7241:
  2134. + ar71xx_mdio_data.is_ar7240 = 1;
  2135. + ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE;
  2136. + ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1;
  2137. + break;
  2138. + case AR71XX_SOC_AR7242:
  2139. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
  2140. + AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
  2141. + AR71XX_ETH0_PLL_SHIFT);
  2142. + break;
  2143. + case AR71XX_SOC_AR9330:
  2144. + case AR71XX_SOC_AR9331:
  2145. + ar71xx_mdio_data.is_ar7240 = 1;
  2146. + ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE;
  2147. + ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1;
  2148. + break;
  2149. + default:
  2150. + break;
  2151. + }
  2152. +
  2153. + ar71xx_mdio_data.phy_mask = phy_mask;
  2154. +
  2155. + platform_device_register(&ar71xx_mdio_device);
  2156. +}
  2157. +
  2158. +struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  2159. +struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  2160. +
  2161. +static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
  2162. +{
  2163. + struct ar71xx_eth_pll_data *pll_data;
  2164. + u32 pll_val;
  2165. +
  2166. + switch (mac) {
  2167. + case 0:
  2168. + pll_data = &ar71xx_eth0_pll_data;
  2169. + break;
  2170. + case 1:
  2171. + pll_data = &ar71xx_eth1_pll_data;
  2172. + break;
  2173. + default:
  2174. + BUG();
  2175. + }
  2176. +
  2177. + switch (speed) {
  2178. + case SPEED_10:
  2179. + pll_val = pll_data->pll_10;
  2180. + break;
  2181. + case SPEED_100:
  2182. + pll_val = pll_data->pll_100;
  2183. + break;
  2184. + case SPEED_1000:
  2185. + pll_val = pll_data->pll_1000;
  2186. + break;
  2187. + default:
  2188. + BUG();
  2189. + }
  2190. +
  2191. + return pll_val;
  2192. +}
  2193. +
  2194. +static void ar71xx_set_pll_ge0(int speed)
  2195. +{
  2196. + u32 val = ar71xx_get_eth_pll(0, speed);
  2197. +
  2198. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
  2199. + val, AR71XX_ETH0_PLL_SHIFT);
  2200. +}
  2201. +
  2202. +static void ar71xx_set_pll_ge1(int speed)
  2203. +{
  2204. + u32 val = ar71xx_get_eth_pll(1, speed);
  2205. +
  2206. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
  2207. + val, AR71XX_ETH1_PLL_SHIFT);
  2208. +}
  2209. +
  2210. +static void ar724x_set_pll_ge0(int speed)
  2211. +{
  2212. + /* TODO */
  2213. +}
  2214. +
  2215. +static void ar724x_set_pll_ge1(int speed)
  2216. +{
  2217. + /* TODO */
  2218. +}
  2219. +
  2220. +static void ar7242_set_pll_ge0(int speed)
  2221. +{
  2222. + u32 val = ar71xx_get_eth_pll(0, speed);
  2223. +
  2224. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR7242_PLL_REG_ETH0_INT_CLOCK,
  2225. + val, AR71XX_ETH0_PLL_SHIFT);
  2226. +}
  2227. +
  2228. +static void ar91xx_set_pll_ge0(int speed)
  2229. +{
  2230. + u32 val = ar71xx_get_eth_pll(0, speed);
  2231. +
  2232. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
  2233. + val, AR91XX_ETH0_PLL_SHIFT);
  2234. +}
  2235. +
  2236. +static void ar91xx_set_pll_ge1(int speed)
  2237. +{
  2238. + u32 val = ar71xx_get_eth_pll(1, speed);
  2239. +
  2240. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
  2241. + val, AR91XX_ETH1_PLL_SHIFT);
  2242. +}
  2243. +
  2244. +static void ar933x_set_pll_ge0(int speed)
  2245. +{
  2246. + /* TODO */
  2247. +}
  2248. +
  2249. +static void ar933x_set_pll_ge1(int speed)
  2250. +{
  2251. + /* TODO */
  2252. +}
  2253. +
  2254. +static void ar71xx_ddr_flush_ge0(void)
  2255. +{
  2256. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
  2257. +}
  2258. +
  2259. +static void ar71xx_ddr_flush_ge1(void)
  2260. +{
  2261. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
  2262. +}
  2263. +
  2264. +static void ar724x_ddr_flush_ge0(void)
  2265. +{
  2266. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
  2267. +}
  2268. +
  2269. +static void ar724x_ddr_flush_ge1(void)
  2270. +{
  2271. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
  2272. +}
  2273. +
  2274. +static void ar91xx_ddr_flush_ge0(void)
  2275. +{
  2276. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
  2277. +}
  2278. +
  2279. +static void ar91xx_ddr_flush_ge1(void)
  2280. +{
  2281. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
  2282. +}
  2283. +
  2284. +static void ar933x_ddr_flush_ge0(void)
  2285. +{
  2286. + ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0);
  2287. +}
  2288. +
  2289. +static void ar933x_ddr_flush_ge1(void)
  2290. +{
  2291. + ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1);
  2292. +}
  2293. +
  2294. +static struct resource ar71xx_eth0_resources[] = {
  2295. + {
  2296. + .name = "mac_base",
  2297. + .flags = IORESOURCE_MEM,
  2298. + .start = AR71XX_GE0_BASE,
  2299. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  2300. + }, {
  2301. + .name = "mii_ctrl",
  2302. + .flags = IORESOURCE_MEM,
  2303. + .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
  2304. + .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
  2305. + }, {
  2306. + .name = "mac_irq",
  2307. + .flags = IORESOURCE_IRQ,
  2308. + .start = AR71XX_CPU_IRQ_GE0,
  2309. + .end = AR71XX_CPU_IRQ_GE0,
  2310. + },
  2311. +};
  2312. +
  2313. +struct ag71xx_platform_data ar71xx_eth0_data = {
  2314. + .reset_bit = RESET_MODULE_GE0_MAC,
  2315. +};
  2316. +
  2317. +struct platform_device ar71xx_eth0_device = {
  2318. + .name = "ag71xx",
  2319. + .id = 0,
  2320. + .resource = ar71xx_eth0_resources,
  2321. + .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
  2322. + .dev = {
  2323. + .platform_data = &ar71xx_eth0_data,
  2324. + },
  2325. +};
  2326. +
  2327. +static struct resource ar71xx_eth1_resources[] = {
  2328. + {
  2329. + .name = "mac_base",
  2330. + .flags = IORESOURCE_MEM,
  2331. + .start = AR71XX_GE1_BASE,
  2332. + .end = AR71XX_GE1_BASE + 0x200 - 1,
  2333. + }, {
  2334. + .name = "mii_ctrl",
  2335. + .flags = IORESOURCE_MEM,
  2336. + .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
  2337. + .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
  2338. + }, {
  2339. + .name = "mac_irq",
  2340. + .flags = IORESOURCE_IRQ,
  2341. + .start = AR71XX_CPU_IRQ_GE1,
  2342. + .end = AR71XX_CPU_IRQ_GE1,
  2343. + },
  2344. +};
  2345. +
  2346. +struct ag71xx_platform_data ar71xx_eth1_data = {
  2347. + .reset_bit = RESET_MODULE_GE1_MAC,
  2348. +};
  2349. +
  2350. +struct platform_device ar71xx_eth1_device = {
  2351. + .name = "ag71xx",
  2352. + .id = 1,
  2353. + .resource = ar71xx_eth1_resources,
  2354. + .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
  2355. + .dev = {
  2356. + .platform_data = &ar71xx_eth1_data,
  2357. + },
  2358. +};
  2359. +
  2360. +#define AR71XX_PLL_VAL_1000 0x00110000
  2361. +#define AR71XX_PLL_VAL_100 0x00001099
  2362. +#define AR71XX_PLL_VAL_10 0x00991099
  2363. +
  2364. +#define AR724X_PLL_VAL_1000 0x00110000
  2365. +#define AR724X_PLL_VAL_100 0x00001099
  2366. +#define AR724X_PLL_VAL_10 0x00991099
  2367. +
  2368. +#define AR7242_PLL_VAL_1000 0x1c000000
  2369. +#define AR7242_PLL_VAL_100 0x00000101
  2370. +#define AR7242_PLL_VAL_10 0x00001616
  2371. +
  2372. +#define AR91XX_PLL_VAL_1000 0x1a000000
  2373. +#define AR91XX_PLL_VAL_100 0x13000a44
  2374. +#define AR91XX_PLL_VAL_10 0x00441099
  2375. +
  2376. +#define AR933X_PLL_VAL_1000 0x00110000
  2377. +#define AR933X_PLL_VAL_100 0x00001099
  2378. +#define AR933X_PLL_VAL_10 0x00991099
  2379. +
  2380. +static void __init ar71xx_init_eth_pll_data(unsigned int id)
  2381. +{
  2382. + struct ar71xx_eth_pll_data *pll_data;
  2383. + u32 pll_10, pll_100, pll_1000;
  2384. +
  2385. + switch (id) {
  2386. + case 0:
  2387. + pll_data = &ar71xx_eth0_pll_data;
  2388. + break;
  2389. + case 1:
  2390. + pll_data = &ar71xx_eth1_pll_data;
  2391. + break;
  2392. + default:
  2393. + BUG();
  2394. + }
  2395. +
  2396. + switch (ar71xx_soc) {
  2397. + case AR71XX_SOC_AR7130:
  2398. + case AR71XX_SOC_AR7141:
  2399. + case AR71XX_SOC_AR7161:
  2400. + pll_10 = AR71XX_PLL_VAL_10;
  2401. + pll_100 = AR71XX_PLL_VAL_100;
  2402. + pll_1000 = AR71XX_PLL_VAL_1000;
  2403. + break;
  2404. +
  2405. + case AR71XX_SOC_AR7240:
  2406. + case AR71XX_SOC_AR7241:
  2407. + pll_10 = AR724X_PLL_VAL_10;
  2408. + pll_100 = AR724X_PLL_VAL_100;
  2409. + pll_1000 = AR724X_PLL_VAL_1000;
  2410. + break;
  2411. +
  2412. + case AR71XX_SOC_AR7242:
  2413. + pll_10 = AR7242_PLL_VAL_10;
  2414. + pll_100 = AR7242_PLL_VAL_100;
  2415. + pll_1000 = AR7242_PLL_VAL_1000;
  2416. + break;
  2417. +
  2418. + case AR71XX_SOC_AR9130:
  2419. + case AR71XX_SOC_AR9132:
  2420. + pll_10 = AR91XX_PLL_VAL_10;
  2421. + pll_100 = AR91XX_PLL_VAL_100;
  2422. + pll_1000 = AR91XX_PLL_VAL_1000;
  2423. + break;
  2424. +
  2425. + case AR71XX_SOC_AR9330:
  2426. + case AR71XX_SOC_AR9331:
  2427. + pll_10 = AR933X_PLL_VAL_10;
  2428. + pll_100 = AR933X_PLL_VAL_100;
  2429. + pll_1000 = AR933X_PLL_VAL_1000;
  2430. + break;
  2431. +
  2432. + default:
  2433. + BUG();
  2434. + }
  2435. +
  2436. + if (!pll_data->pll_10)
  2437. + pll_data->pll_10 = pll_10;
  2438. +
  2439. + if (!pll_data->pll_100)
  2440. + pll_data->pll_100 = pll_100;
  2441. +
  2442. + if (!pll_data->pll_1000)
  2443. + pll_data->pll_1000 = pll_1000;
  2444. +}
  2445. +
  2446. +static int ar71xx_eth_instance __initdata;
  2447. +void __init ar71xx_add_device_eth(unsigned int id)
  2448. +{
  2449. + struct platform_device *pdev;
  2450. + struct ag71xx_platform_data *pdata;
  2451. +
  2452. + ar71xx_init_eth_pll_data(id);
  2453. +
  2454. + switch (id) {
  2455. + case 0:
  2456. + switch (ar71xx_eth0_data.phy_if_mode) {
  2457. + case PHY_INTERFACE_MODE_MII:
  2458. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
  2459. + break;
  2460. + case PHY_INTERFACE_MODE_GMII:
  2461. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
  2462. + break;
  2463. + case PHY_INTERFACE_MODE_RGMII:
  2464. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
  2465. + break;
  2466. + case PHY_INTERFACE_MODE_RMII:
  2467. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
  2468. + break;
  2469. + default:
  2470. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2471. + "for eth0\n");
  2472. + return;
  2473. + }
  2474. + pdev = &ar71xx_eth0_device;
  2475. + break;
  2476. + case 1:
  2477. + switch (ar71xx_eth1_data.phy_if_mode) {
  2478. + case PHY_INTERFACE_MODE_RMII:
  2479. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
  2480. + break;
  2481. + case PHY_INTERFACE_MODE_RGMII:
  2482. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
  2483. + break;
  2484. + default:
  2485. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2486. + "for eth1\n");
  2487. + return;
  2488. + }
  2489. + pdev = &ar71xx_eth1_device;
  2490. + break;
  2491. + default:
  2492. + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
  2493. + return;
  2494. + }
  2495. +
  2496. + pdata = pdev->dev.platform_data;
  2497. +
  2498. + switch (ar71xx_soc) {
  2499. + case AR71XX_SOC_AR7130:
  2500. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2501. + : ar71xx_ddr_flush_ge0;
  2502. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2503. + : ar71xx_set_pll_ge0;
  2504. + break;
  2505. +
  2506. + case AR71XX_SOC_AR7141:
  2507. + case AR71XX_SOC_AR7161:
  2508. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2509. + : ar71xx_ddr_flush_ge0;
  2510. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2511. + : ar71xx_set_pll_ge0;
  2512. + pdata->has_gbit = 1;
  2513. + break;
  2514. +
  2515. + case AR71XX_SOC_AR7242:
  2516. + ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO |
  2517. + RESET_MODULE_GE0_PHY;
  2518. + ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO |
  2519. + RESET_MODULE_GE1_PHY;
  2520. + pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
  2521. + : ar724x_ddr_flush_ge0;
  2522. + pdata->set_pll = id ? ar724x_set_pll_ge1
  2523. + : ar7242_set_pll_ge0;
  2524. + pdata->has_gbit = 1;
  2525. + pdata->is_ar724x = 1;
  2526. +
  2527. + if (!pdata->fifo_cfg1)
  2528. + pdata->fifo_cfg1 = 0x0010ffff;
  2529. + if (!pdata->fifo_cfg2)
  2530. + pdata->fifo_cfg2 = 0x015500aa;
  2531. + if (!pdata->fifo_cfg3)
  2532. + pdata->fifo_cfg3 = 0x01f00140;
  2533. + break;
  2534. +
  2535. + case AR71XX_SOC_AR7241:
  2536. + ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
  2537. + ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
  2538. + /* fall through */
  2539. + case AR71XX_SOC_AR7240:
  2540. + ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY;
  2541. + ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY;
  2542. + pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
  2543. + : ar724x_ddr_flush_ge0;
  2544. + pdata->set_pll = id ? ar724x_set_pll_ge1
  2545. + : ar724x_set_pll_ge0;
  2546. + pdata->is_ar724x = 1;
  2547. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  2548. + pdata->is_ar7240 = 1;
  2549. +
  2550. + if (!pdata->fifo_cfg1)
  2551. + pdata->fifo_cfg1 = 0x0010ffff;
  2552. + if (!pdata->fifo_cfg2)
  2553. + pdata->fifo_cfg2 = 0x015500aa;
  2554. + if (!pdata->fifo_cfg3)
  2555. + pdata->fifo_cfg3 = 0x01f00140;
  2556. + break;
  2557. +
  2558. + case AR71XX_SOC_AR9130:
  2559. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2560. + : ar91xx_ddr_flush_ge0;
  2561. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2562. + : ar91xx_set_pll_ge0;
  2563. + pdata->is_ar91xx = 1;
  2564. + break;
  2565. +
  2566. + case AR71XX_SOC_AR9132:
  2567. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2568. + : ar91xx_ddr_flush_ge0;
  2569. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2570. + : ar91xx_set_pll_ge0;
  2571. + pdata->is_ar91xx = 1;
  2572. + pdata->has_gbit = 1;
  2573. + break;
  2574. +
  2575. + case AR71XX_SOC_AR9330:
  2576. + case AR71XX_SOC_AR9331:
  2577. + ar71xx_eth0_data.reset_bit = AR933X_RESET_GE0_MAC |
  2578. + AR933X_RESET_GE0_MDIO;
  2579. + ar71xx_eth1_data.reset_bit = AR933X_RESET_GE1_MAC |
  2580. + AR933X_RESET_GE1_MDIO;
  2581. + pdata->ddr_flush = id ? ar933x_ddr_flush_ge1
  2582. + : ar933x_ddr_flush_ge0;
  2583. + pdata->set_pll = id ? ar933x_set_pll_ge1
  2584. + : ar933x_set_pll_ge0;
  2585. + pdata->has_gbit = 1;
  2586. + pdata->is_ar724x = 1;
  2587. +
  2588. + if (!pdata->fifo_cfg1)
  2589. + pdata->fifo_cfg1 = 0x0010ffff;
  2590. + if (!pdata->fifo_cfg2)
  2591. + pdata->fifo_cfg2 = 0x015500aa;
  2592. + if (!pdata->fifo_cfg3)
  2593. + pdata->fifo_cfg3 = 0x01f00140;
  2594. + break;
  2595. +
  2596. + default:
  2597. + BUG();
  2598. + }
  2599. +
  2600. + switch (pdata->phy_if_mode) {
  2601. + case PHY_INTERFACE_MODE_GMII:
  2602. + case PHY_INTERFACE_MODE_RGMII:
  2603. + if (!pdata->has_gbit) {
  2604. + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
  2605. + id);
  2606. + return;
  2607. + }
  2608. + /* fallthrough */
  2609. + default:
  2610. + break;
  2611. + }
  2612. +
  2613. + if (!is_valid_ether_addr(pdata->mac_addr)) {
  2614. + random_ether_addr(pdata->mac_addr);
  2615. + printk(KERN_DEBUG
  2616. + "ar71xx: using random MAC address for eth%d\n",
  2617. + ar71xx_eth_instance);
  2618. + }
  2619. +
  2620. + if (pdata->mii_bus_dev == NULL)
  2621. + pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
  2622. +
  2623. + /* Reset the device */
  2624. + ar71xx_device_stop(pdata->reset_bit);
  2625. + mdelay(100);
  2626. +
  2627. + ar71xx_device_start(pdata->reset_bit);
  2628. + mdelay(100);
  2629. +
  2630. + platform_device_register(pdev);
  2631. + ar71xx_eth_instance++;
  2632. +}
  2633. +
  2634. +static struct resource ar71xx_spi_resources[] = {
  2635. + [0] = {
  2636. + .start = AR71XX_SPI_BASE,
  2637. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  2638. + .flags = IORESOURCE_MEM,
  2639. + },
  2640. +};
  2641. +
  2642. +static struct platform_device ar71xx_spi_device = {
  2643. + .name = "ar71xx-spi",
  2644. + .id = -1,
  2645. + .resource = ar71xx_spi_resources,
  2646. + .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
  2647. +};
  2648. +
  2649. +void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2650. + struct spi_board_info const *info,
  2651. + unsigned n)
  2652. +{
  2653. + spi_register_board_info(info, n);
  2654. + ar71xx_spi_device.dev.platform_data = pdata;
  2655. + platform_device_register(&ar71xx_spi_device);
  2656. +}
  2657. +
  2658. +void __init ar71xx_add_device_wdt(void)
  2659. +{
  2660. + platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
  2661. +}
  2662. +
  2663. +void __init ar71xx_set_mac_base(unsigned char *mac)
  2664. +{
  2665. + memcpy(ar71xx_mac_base, mac, ETH_ALEN);
  2666. +}
  2667. +
  2668. +void __init ar71xx_parse_mac_addr(char *mac_str)
  2669. +{
  2670. + u8 tmp[ETH_ALEN];
  2671. + int t;
  2672. +
  2673. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  2674. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2675. +
  2676. + if (t != ETH_ALEN)
  2677. + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
  2678. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2679. +
  2680. + if (t == ETH_ALEN)
  2681. + ar71xx_set_mac_base(tmp);
  2682. + else
  2683. + printk(KERN_DEBUG "ar71xx: failed to parse mac address "
  2684. + "\"%s\"\n", mac_str);
  2685. +}
  2686. +
  2687. +static int __init ar71xx_ethaddr_setup(char *str)
  2688. +{
  2689. + ar71xx_parse_mac_addr(str);
  2690. + return 1;
  2691. +}
  2692. +__setup("ethaddr=", ar71xx_ethaddr_setup);
  2693. +
  2694. +static int __init ar71xx_kmac_setup(char *str)
  2695. +{
  2696. + ar71xx_parse_mac_addr(str);
  2697. + return 1;
  2698. +}
  2699. +__setup("kmac=", ar71xx_kmac_setup);
  2700. +
  2701. +void __init ar71xx_init_mac(unsigned char *dst, const unsigned char *src,
  2702. + unsigned offset)
  2703. +{
  2704. + u32 t;
  2705. +
  2706. + if (!is_valid_ether_addr(src)) {
  2707. + memset(dst, '\0', ETH_ALEN);
  2708. + return;
  2709. + }
  2710. +
  2711. + t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]);
  2712. + t += offset;
  2713. +
  2714. + dst[0] = src[0];
  2715. + dst[1] = src[1];
  2716. + dst[2] = src[2];
  2717. + dst[3] = (t >> 16) & 0xff;
  2718. + dst[4] = (t >> 8) & 0xff;
  2719. + dst[5] = t & 0xff;
  2720. +}
  2721. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h
  2722. --- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100
  2723. +++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-08-24 18:17:23.000000000 +0200
  2724. @@ -0,0 +1,50 @@
  2725. +/*
  2726. + * Atheros AR71xx SoC device definitions
  2727. + *
  2728. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2729. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2730. + *
  2731. + * This program is free software; you can redistribute it and/or modify it
  2732. + * under the terms of the GNU General Public License version 2 as published
  2733. + * by the Free Software Foundation.
  2734. + */
  2735. +
  2736. +#ifndef __AR71XX_DEVICES_H
  2737. +#define __AR71XX_DEVICES_H
  2738. +
  2739. +#include <asm/mach-ar71xx/platform.h>
  2740. +
  2741. +struct platform_device;
  2742. +
  2743. +void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2744. + struct spi_board_info const *info,
  2745. + unsigned n) __init;
  2746. +
  2747. +extern unsigned char ar71xx_mac_base[] __initdata;
  2748. +void ar71xx_parse_mac_addr(char *mac_str) __init;
  2749. +void ar71xx_init_mac(unsigned char *dst, const unsigned char *src,
  2750. + unsigned offset) __init;
  2751. +
  2752. +struct ar71xx_eth_pll_data {
  2753. + u32 pll_10;
  2754. + u32 pll_100;
  2755. + u32 pll_1000;
  2756. +};
  2757. +
  2758. +extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  2759. +extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  2760. +
  2761. +extern struct ag71xx_platform_data ar71xx_eth0_data;
  2762. +extern struct ag71xx_platform_data ar71xx_eth1_data;
  2763. +extern struct platform_device ar71xx_eth0_device;
  2764. +extern struct platform_device ar71xx_eth1_device;
  2765. +void ar71xx_add_device_eth(unsigned int id) __init;
  2766. +
  2767. +extern struct platform_device ar71xx_mdio_device;
  2768. +void ar71xx_add_device_mdio(u32 phy_mask) __init;
  2769. +
  2770. +void ar71xx_add_device_uart(void) __init;
  2771. +
  2772. +void ar71xx_add_device_wdt(void) __init;
  2773. +
  2774. +#endif /* __AR71XX_DEVICES_H */
  2775. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c
  2776. --- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100
  2777. +++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-08-24 18:17:23.000000000 +0200
  2778. @@ -0,0 +1,96 @@
  2779. +/*
  2780. + * Atheros AR7xxx/AR9xxx SoC early printk support
  2781. + *
  2782. + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
  2783. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2784. + *
  2785. + * This program is free software; you can redistribute it and/or modify it
  2786. + * under the terms of the GNU General Public License version 2 as published
  2787. + * by the Free Software Foundation.
  2788. + */
  2789. +
  2790. +#include <linux/errno.h>
  2791. +#include <linux/io.h>
  2792. +#include <linux/serial_reg.h>
  2793. +#include <asm/addrspace.h>
  2794. +
  2795. +#include <asm/mach-ar71xx/ar71xx.h>
  2796. +#include <asm/mach-ar71xx/ar933x_uart.h>
  2797. +
  2798. +static void (*_prom_putchar) (unsigned char);
  2799. +
  2800. +static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
  2801. +{
  2802. + u32 t;
  2803. +
  2804. + do {
  2805. + t = __raw_readl(reg);
  2806. + if ((t & mask) == val)
  2807. + break;
  2808. + } while (1);
  2809. +}
  2810. +
  2811. +static void prom_putchar_ar71xx(unsigned char ch)
  2812. +{
  2813. + void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
  2814. +
  2815. + prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
  2816. + __raw_writel(ch, base + UART_TX * 4);
  2817. + prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
  2818. +}
  2819. +
  2820. +static void prom_putchar_ar933x(unsigned char ch)
  2821. +{
  2822. + void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
  2823. +
  2824. + prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
  2825. + AR933X_UART_DATA_TX_CSR);
  2826. + __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG);
  2827. + prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
  2828. + AR933X_UART_DATA_TX_CSR);
  2829. +}
  2830. +
  2831. +static void prom_putchar_dummy(unsigned char ch)
  2832. +{
  2833. + /* nothing to do */
  2834. +}
  2835. +
  2836. +static void prom_putchar_init(void)
  2837. +{
  2838. + void __iomem *base;
  2839. + u32 id;
  2840. +
  2841. + base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
  2842. + id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
  2843. + id &= REV_ID_MAJOR_MASK;
  2844. +
  2845. + switch (id) {
  2846. + case REV_ID_MAJOR_AR71XX:
  2847. + case REV_ID_MAJOR_AR7240:
  2848. + case REV_ID_MAJOR_AR7241:
  2849. + case REV_ID_MAJOR_AR7242:
  2850. + case REV_ID_MAJOR_AR913X:
  2851. + case REV_ID_MAJOR_AR9341:
  2852. + case REV_ID_MAJOR_AR9342:
  2853. + case REV_ID_MAJOR_AR9344:
  2854. + _prom_putchar = prom_putchar_ar71xx;
  2855. + break;
  2856. +
  2857. + case REV_ID_MAJOR_AR9330:
  2858. + case REV_ID_MAJOR_AR9331:
  2859. + _prom_putchar = prom_putchar_ar933x;
  2860. + break;
  2861. +
  2862. + default:
  2863. + _prom_putchar = prom_putchar_dummy;
  2864. + break;
  2865. + }
  2866. +}
  2867. +
  2868. +void prom_putchar(unsigned char ch)
  2869. +{
  2870. + if (!_prom_putchar)
  2871. + prom_putchar_init();
  2872. +
  2873. + _prom_putchar(ch);
  2874. +}
  2875. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c
  2876. --- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
  2877. +++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-08-24 18:17:23.000000000 +0200
  2878. @@ -0,0 +1,193 @@
  2879. +/*
  2880. + * Atheros AR7XXX/AR9XXX SoC GPIO API support
  2881. + *
  2882. + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
  2883. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2884. + *
  2885. + * This program is free software; you can redistribute it and/or modify it
  2886. + * under the terms of the GNU General Public License version 2 as published
  2887. + * by the Free Software Foundation.
  2888. + */
  2889. +
  2890. +#include <linux/kernel.h>
  2891. +#include <linux/init.h>
  2892. +#include <linux/module.h>
  2893. +#include <linux/types.h>
  2894. +#include <linux/spinlock.h>
  2895. +#include <linux/io.h>
  2896. +#include <linux/ioport.h>
  2897. +#include <linux/gpio.h>
  2898. +
  2899. +#include <asm/mach-ar71xx/ar71xx.h>
  2900. +
  2901. +static DEFINE_SPINLOCK(ar71xx_gpio_lock);
  2902. +
  2903. +unsigned long ar71xx_gpio_count;
  2904. +EXPORT_SYMBOL(ar71xx_gpio_count);
  2905. +
  2906. +void __ar71xx_gpio_set_value(unsigned gpio, int value)
  2907. +{
  2908. + void __iomem *base = ar71xx_gpio_base;
  2909. +
  2910. + if (value)
  2911. + __raw_writel(1 << gpio, base + GPIO_REG_SET);
  2912. + else
  2913. + __raw_writel(1 << gpio, base + GPIO_REG_CLEAR);
  2914. +}
  2915. +EXPORT_SYMBOL(__ar71xx_gpio_set_value);
  2916. +
  2917. +int __ar71xx_gpio_get_value(unsigned gpio)
  2918. +{
  2919. + return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1;
  2920. +}
  2921. +EXPORT_SYMBOL(__ar71xx_gpio_get_value);
  2922. +
  2923. +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  2924. +{
  2925. + return __ar71xx_gpio_get_value(offset);
  2926. +}
  2927. +
  2928. +static void ar71xx_gpio_set_value(struct gpio_chip *chip,
  2929. + unsigned offset, int value)
  2930. +{
  2931. + __ar71xx_gpio_set_value(offset, value);
  2932. +}
  2933. +
  2934. +static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
  2935. + unsigned offset)
  2936. +{
  2937. + void __iomem *base = ar71xx_gpio_base;
  2938. + unsigned long flags;
  2939. +
  2940. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2941. +
  2942. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset),
  2943. + base + GPIO_REG_OE);
  2944. +
  2945. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2946. +
  2947. + return 0;
  2948. +}
  2949. +
  2950. +static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
  2951. + unsigned offset, int value)
  2952. +{
  2953. + void __iomem *base = ar71xx_gpio_base;
  2954. + unsigned long flags;
  2955. +
  2956. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2957. +
  2958. + if (value)
  2959. + __raw_writel(1 << offset, base + GPIO_REG_SET);
  2960. + else
  2961. + __raw_writel(1 << offset, base + GPIO_REG_CLEAR);
  2962. +
  2963. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset),
  2964. + base + GPIO_REG_OE);
  2965. +
  2966. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2967. +
  2968. + return 0;
  2969. +}
  2970. +
  2971. +static struct gpio_chip ar71xx_gpio_chip = {
  2972. + .label = "ar71xx",
  2973. + .get = ar71xx_gpio_get_value,
  2974. + .set = ar71xx_gpio_set_value,
  2975. + .direction_input = ar71xx_gpio_direction_input,
  2976. + .direction_output = ar71xx_gpio_direction_output,
  2977. + .base = 0,
  2978. + .ngpio = AR71XX_GPIO_COUNT,
  2979. +};
  2980. +
  2981. +void ar71xx_gpio_function_enable(u32 mask)
  2982. +{
  2983. + void __iomem *base = ar71xx_gpio_base;
  2984. + unsigned long flags;
  2985. +
  2986. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2987. +
  2988. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask,
  2989. + base + GPIO_REG_FUNC);
  2990. + /* flush write */
  2991. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2992. +
  2993. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2994. +}
  2995. +
  2996. +void ar71xx_gpio_function_disable(u32 mask)
  2997. +{
  2998. + void __iomem *base = ar71xx_gpio_base;
  2999. + unsigned long flags;
  3000. +
  3001. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  3002. +
  3003. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask,
  3004. + base + GPIO_REG_FUNC);
  3005. + /* flush write */
  3006. + (void) __raw_readl(base + GPIO_REG_FUNC);
  3007. +
  3008. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  3009. +}
  3010. +
  3011. +void ar71xx_gpio_function_setup(u32 set, u32 clear)
  3012. +{
  3013. + void __iomem *base = ar71xx_gpio_base;
  3014. + unsigned long flags;
  3015. +
  3016. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  3017. +
  3018. + __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set,
  3019. + base + GPIO_REG_FUNC);
  3020. + /* flush write */
  3021. + (void) __raw_readl(base + GPIO_REG_FUNC);
  3022. +
  3023. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  3024. +}
  3025. +EXPORT_SYMBOL(ar71xx_gpio_function_setup);
  3026. +
  3027. +void __init ar71xx_gpio_init(void)
  3028. +{
  3029. + int err;
  3030. +
  3031. + if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
  3032. + "AR71xx GPIO controller"))
  3033. + panic("cannot allocate AR71xx GPIO registers page");
  3034. +
  3035. + switch (ar71xx_soc) {
  3036. + case AR71XX_SOC_AR7130:
  3037. + case AR71XX_SOC_AR7141:
  3038. + case AR71XX_SOC_AR7161:
  3039. + ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
  3040. + break;
  3041. +
  3042. + case AR71XX_SOC_AR7240:
  3043. + case AR71XX_SOC_AR7241:
  3044. + case AR71XX_SOC_AR7242:
  3045. + ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT;
  3046. + break;
  3047. +
  3048. + case AR71XX_SOC_AR9130:
  3049. + case AR71XX_SOC_AR9132:
  3050. + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
  3051. + break;
  3052. +
  3053. + case AR71XX_SOC_AR9330:
  3054. + case AR71XX_SOC_AR9331:
  3055. + ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT;
  3056. + break;
  3057. +
  3058. + case AR71XX_SOC_AR9341:
  3059. + case AR71XX_SOC_AR9342:
  3060. + case AR71XX_SOC_AR9344:
  3061. + ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT;
  3062. + break;
  3063. +
  3064. + default:
  3065. + BUG();
  3066. + }
  3067. +
  3068. + err = gpiochip_add(&ar71xx_gpio_chip);
  3069. + if (err)
  3070. + panic("cannot add AR71xx GPIO chip, error=%d", err);
  3071. +}
  3072. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx/irq.c
  3073. --- linux-2.6.39.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100
  3074. +++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-08-24 18:17:23.000000000 +0200
  3075. @@ -0,0 +1,377 @@
  3076. +/*
  3077. + * Atheros AR71xx SoC specific interrupt handling
  3078. + *
  3079. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  3080. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  3081. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3082. + *
  3083. + * Parts of this file are based on Atheros 2.6.15 BSP
  3084. + * Parts of this file are based on Atheros 2.6.31 BSP
  3085. + *
  3086. + * This program is free software; you can redistribute it and/or modify it
  3087. + * under the terms of the GNU General Public License version 2 as published
  3088. + * by the Free Software Foundation.
  3089. + */
  3090. +
  3091. +#include <linux/kernel.h>
  3092. +#include <linux/init.h>
  3093. +#include <linux/interrupt.h>
  3094. +#include <linux/irq.h>
  3095. +
  3096. +#include <asm/irq_cpu.h>
  3097. +#include <asm/mipsregs.h>
  3098. +
  3099. +#include <asm/mach-ar71xx/ar71xx.h>
  3100. +
  3101. +static void ar71xx_gpio_irq_dispatch(void)
  3102. +{
  3103. + void __iomem *base = ar71xx_gpio_base;
  3104. + u32 pending;
  3105. +
  3106. + pending = __raw_readl(base + GPIO_REG_INT_PENDING) &
  3107. + __raw_readl(base + GPIO_REG_INT_ENABLE);
  3108. +
  3109. + if (pending)
  3110. + do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
  3111. + else
  3112. + spurious_interrupt();
  3113. +}
  3114. +
  3115. +static void ar71xx_gpio_irq_unmask(struct irq_data *d)
  3116. +{
  3117. + unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE;
  3118. + void __iomem *base = ar71xx_gpio_base;
  3119. + u32 t;
  3120. +
  3121. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  3122. + __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE);
  3123. +
  3124. + /* flush write */
  3125. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  3126. +}
  3127. +
  3128. +static void ar71xx_gpio_irq_mask(struct irq_data *d)
  3129. +{
  3130. + unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE;
  3131. + void __iomem *base = ar71xx_gpio_base;
  3132. + u32 t;
  3133. +
  3134. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  3135. + __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE);
  3136. +
  3137. + /* flush write */
  3138. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  3139. +}
  3140. +
  3141. +static struct irq_chip ar71xx_gpio_irq_chip = {
  3142. + .name = "AR71XX GPIO",
  3143. + .irq_unmask = ar71xx_gpio_irq_unmask,
  3144. + .irq_mask = ar71xx_gpio_irq_mask,
  3145. + .irq_mask_ack = ar71xx_gpio_irq_mask,
  3146. +};
  3147. +
  3148. +static struct irqaction ar71xx_gpio_irqaction = {
  3149. + .handler = no_action,
  3150. + .name = "cascade [AR71XX GPIO]",
  3151. +};
  3152. +
  3153. +#define GPIO_INT_ALL 0xffff
  3154. +
  3155. +static void __init ar71xx_gpio_irq_init(void)
  3156. +{
  3157. + void __iomem *base = ar71xx_gpio_base;
  3158. + int i;
  3159. +
  3160. + __raw_writel(0, base + GPIO_REG_INT_ENABLE);
  3161. + __raw_writel(0, base + GPIO_REG_INT_PENDING);
  3162. +
  3163. + /* setup type of all GPIO interrupts to level sensitive */
  3164. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE);
  3165. +
  3166. + /* setup polarity of all GPIO interrupts to active high */
  3167. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY);
  3168. +
  3169. + for (i = AR71XX_GPIO_IRQ_BASE;
  3170. + i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++)
  3171. + irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip,
  3172. + handle_level_irq);
  3173. +
  3174. + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
  3175. +}
  3176. +
  3177. +static void ar71xx_misc_irq_dispatch(void)
  3178. +{
  3179. + u32 pending;
  3180. +
  3181. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
  3182. + & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
  3183. +
  3184. + if (pending & MISC_INT_UART)
  3185. + do_IRQ(AR71XX_MISC_IRQ_UART);
  3186. +
  3187. + else if (pending & MISC_INT_DMA)
  3188. + do_IRQ(AR71XX_MISC_IRQ_DMA);
  3189. +
  3190. + else if (pending & MISC_INT_PERFC)
  3191. + do_IRQ(AR71XX_MISC_IRQ_PERFC);
  3192. +
  3193. + else if (pending & MISC_INT_TIMER)
  3194. + do_IRQ(AR71XX_MISC_IRQ_TIMER);
  3195. +
  3196. + else if (pending & MISC_INT_OHCI)
  3197. + do_IRQ(AR71XX_MISC_IRQ_OHCI);
  3198. +
  3199. + else if (pending & MISC_INT_ERROR)
  3200. + do_IRQ(AR71XX_MISC_IRQ_ERROR);
  3201. +
  3202. + else if (pending & MISC_INT_GPIO)
  3203. + ar71xx_gpio_irq_dispatch();
  3204. +
  3205. + else if (pending & MISC_INT_WDOG)
  3206. + do_IRQ(AR71XX_MISC_IRQ_WDOG);
  3207. +
  3208. + else if (pending & MISC_INT_TIMER2)
  3209. + do_IRQ(AR71XX_MISC_IRQ_TIMER2);
  3210. +
  3211. + else if (pending & MISC_INT_TIMER3)
  3212. + do_IRQ(AR71XX_MISC_IRQ_TIMER3);
  3213. +
  3214. + else if (pending & MISC_INT_TIMER4)
  3215. + do_IRQ(AR71XX_MISC_IRQ_TIMER4);
  3216. +
  3217. + else if (pending & MISC_INT_DDR_PERF)
  3218. + do_IRQ(AR71XX_MISC_IRQ_DDR_PERF);
  3219. +
  3220. + else if (pending & MISC_INT_ENET_LINK)
  3221. + do_IRQ(AR71XX_MISC_IRQ_ENET_LINK);
  3222. +
  3223. + else
  3224. + spurious_interrupt();
  3225. +}
  3226. +
  3227. +static void ar71xx_misc_irq_unmask(struct irq_data *d)
  3228. +{
  3229. + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
  3230. + void __iomem *base = ar71xx_reset_base;
  3231. + u32 t;
  3232. +
  3233. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3234. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3235. +
  3236. + /* flush write */
  3237. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3238. +}
  3239. +
  3240. +static void ar71xx_misc_irq_mask(struct irq_data *d)
  3241. +{
  3242. + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
  3243. + void __iomem *base = ar71xx_reset_base;
  3244. + u32 t;
  3245. +
  3246. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3247. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3248. +
  3249. + /* flush write */
  3250. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3251. +}
  3252. +
  3253. +static void ar724x_misc_irq_ack(struct irq_data *d)
  3254. +{
  3255. + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
  3256. + void __iomem *base = ar71xx_reset_base;
  3257. + u32 t;
  3258. +
  3259. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  3260. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
  3261. +
  3262. + /* flush write */
  3263. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  3264. +}
  3265. +
  3266. +static struct irq_chip ar71xx_misc_irq_chip = {
  3267. + .name = "AR71XX MISC",
  3268. + .irq_unmask = ar71xx_misc_irq_unmask,
  3269. + .irq_mask = ar71xx_misc_irq_mask,
  3270. +};
  3271. +
  3272. +static struct irqaction ar71xx_misc_irqaction = {
  3273. + .handler = no_action,
  3274. + .name = "cascade [AR71XX MISC]",
  3275. +};
  3276. +
  3277. +static void __init ar71xx_misc_irq_init(void)
  3278. +{
  3279. + void __iomem *base = ar71xx_reset_base;
  3280. + int i;
  3281. +
  3282. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  3283. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
  3284. +
  3285. + switch (ar71xx_soc) {
  3286. + case AR71XX_SOC_AR7240:
  3287. + case AR71XX_SOC_AR7241:
  3288. + case AR71XX_SOC_AR7242:
  3289. + case AR71XX_SOC_AR9330:
  3290. + case AR71XX_SOC_AR9331:
  3291. + case AR71XX_SOC_AR9341:
  3292. + case AR71XX_SOC_AR9342:
  3293. + case AR71XX_SOC_AR9344:
  3294. + ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
  3295. + break;
  3296. + default:
  3297. + ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
  3298. + break;
  3299. + }
  3300. +
  3301. + for (i = AR71XX_MISC_IRQ_BASE;
  3302. + i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++)
  3303. + irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip,
  3304. + handle_level_irq);
  3305. +
  3306. + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
  3307. +}
  3308. +
  3309. +/*
  3310. + * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
  3311. + * these devices typically allocate coherent DMA memory, however the
  3312. + * DMA controller may still have some unsynchronized data in the FIFO.
  3313. + * Issue a flush in the handlers to ensure that the driver sees
  3314. + * the update.
  3315. + */
  3316. +static void ar71xx_ip2_handler(void)
  3317. +{
  3318. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_PCI);
  3319. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  3320. +}
  3321. +
  3322. +static void ar724x_ip2_handler(void)
  3323. +{
  3324. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_PCIE);
  3325. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  3326. +}
  3327. +
  3328. +static void ar913x_ip2_handler(void)
  3329. +{
  3330. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_WMAC);
  3331. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  3332. +}
  3333. +
  3334. +static void ar933x_ip2_handler(void)
  3335. +{
  3336. + ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC);
  3337. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  3338. +}
  3339. +
  3340. +static void ar934x_ip2_handler(void)
  3341. +{
  3342. + ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE);
  3343. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  3344. +}
  3345. +
  3346. +static void ar71xx_ip3_handler(void)
  3347. +{
  3348. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB);
  3349. + do_IRQ(AR71XX_CPU_IRQ_USB);
  3350. +}
  3351. +
  3352. +static void ar724x_ip3_handler(void)
  3353. +{
  3354. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB);
  3355. + do_IRQ(AR71XX_CPU_IRQ_USB);
  3356. +}
  3357. +
  3358. +static void ar913x_ip3_handler(void)
  3359. +{
  3360. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB);
  3361. + do_IRQ(AR71XX_CPU_IRQ_USB);
  3362. +}
  3363. +
  3364. +static void ar933x_ip3_handler(void)
  3365. +{
  3366. + ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB);
  3367. + do_IRQ(AR71XX_CPU_IRQ_USB);
  3368. +}
  3369. +
  3370. +static void ar934x_ip3_handler(void)
  3371. +{
  3372. + do_IRQ(AR71XX_CPU_IRQ_USB);
  3373. +}
  3374. +
  3375. +static void (*ip2_handler)(void);
  3376. +static void (*ip3_handler)(void);
  3377. +
  3378. +asmlinkage void plat_irq_dispatch(void)
  3379. +{
  3380. + unsigned long pending;
  3381. +
  3382. + pending = read_c0_status() & read_c0_cause() & ST0_IM;
  3383. +
  3384. + if (pending & STATUSF_IP7)
  3385. + do_IRQ(AR71XX_CPU_IRQ_TIMER);
  3386. +
  3387. + else if (pending & STATUSF_IP2)
  3388. + ip2_handler();
  3389. +
  3390. + else if (pending & STATUSF_IP4)
  3391. + do_IRQ(AR71XX_CPU_IRQ_GE0);
  3392. +
  3393. + else if (pending & STATUSF_IP5)
  3394. + do_IRQ(AR71XX_CPU_IRQ_GE1);
  3395. +
  3396. + else if (pending & STATUSF_IP3)
  3397. + ip3_handler();
  3398. +
  3399. + else if (pending & STATUSF_IP6)
  3400. + ar71xx_misc_irq_dispatch();
  3401. +
  3402. + spurious_interrupt();
  3403. +}
  3404. +
  3405. +void __init arch_init_irq(void)
  3406. +{
  3407. + switch (ar71xx_soc) {
  3408. + case AR71XX_SOC_AR7130:
  3409. + case AR71XX_SOC_AR7141:
  3410. + case AR71XX_SOC_AR7161:
  3411. + ip2_handler = ar71xx_ip2_handler;
  3412. + ip3_handler = ar71xx_ip3_handler;
  3413. + break;
  3414. +
  3415. + case AR71XX_SOC_AR7240:
  3416. + case AR71XX_SOC_AR7241:
  3417. + case AR71XX_SOC_AR7242:
  3418. + ip2_handler = ar724x_ip2_handler;
  3419. + ip3_handler = ar724x_ip3_handler;
  3420. + break;
  3421. +
  3422. + case AR71XX_SOC_AR9130:
  3423. + case AR71XX_SOC_AR9132:
  3424. + ip2_handler = ar913x_ip2_handler;
  3425. + ip3_handler = ar913x_ip3_handler;
  3426. + break;
  3427. +
  3428. + case AR71XX_SOC_AR9330:
  3429. + case AR71XX_SOC_AR9331:
  3430. + ip2_handler = ar933x_ip2_handler;
  3431. + ip3_handler = ar933x_ip3_handler;
  3432. + break;
  3433. +
  3434. + case AR71XX_SOC_AR9341:
  3435. + case AR71XX_SOC_AR9342:
  3436. + case AR71XX_SOC_AR9344:
  3437. + ip2_handler = ar934x_ip2_handler;
  3438. + ip3_handler = ar934x_ip3_handler;
  3439. + break;
  3440. +
  3441. + default:
  3442. + BUG();
  3443. + }
  3444. +
  3445. + mips_cpu_irq_init();
  3446. +
  3447. + ar71xx_misc_irq_init();
  3448. +
  3449. + cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC;
  3450. +
  3451. + ar71xx_gpio_irq_init();
  3452. +}
  3453. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c linux-2.6.39/arch/mips/ar71xx/mach-ap121.c
  3454. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c 1970-01-01 01:00:00.000000000 +0100
  3455. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap121.c 2011-08-24 18:17:23.000000000 +0200
  3456. @@ -0,0 +1,245 @@
  3457. +/*
  3458. + * Atheros AP121 board support
  3459. + *
  3460. + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
  3461. + *
  3462. + * This program is free software; you can redistribute it and/or modify it
  3463. + * under the terms of the GNU General Public License version 2 as published
  3464. + * by the Free Software Foundation.
  3465. + */
  3466. +
  3467. +#include <linux/mtd/mtd.h>
  3468. +#include <linux/mtd/partitions.h>
  3469. +#include <linux/spi/flash.h>
  3470. +
  3471. +#include "machtype.h"
  3472. +#include "devices.h"
  3473. +#include "dev-ar9xxx-wmac.h"
  3474. +#include "dev-gpio-buttons.h"
  3475. +#include "dev-leds-gpio.h"
  3476. +#include "dev-m25p80.h"
  3477. +#include "dev-usb.h"
  3478. +
  3479. +#define AP121_GPIO_LED_WLAN 0
  3480. +#define AP121_GPIO_LED_USB 1
  3481. +
  3482. +#define AP121_GPIO_BTN_JUMPSTART 11
  3483. +#define AP121_GPIO_BTN_RESET 12
  3484. +
  3485. +#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
  3486. +#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
  3487. +
  3488. +#define AP121_MAC0_OFFSET 0x0000
  3489. +#define AP121_MAC1_OFFSET 0x0006
  3490. +#define AP121_CALDATA_OFFSET 0x1000
  3491. +#define AP121_WMAC_MAC_OFFSET 0x1002
  3492. +
  3493. +#define AP121_MINI_GPIO_LED_WLAN 0
  3494. +#define AP121_MINI_GPIO_BTN_JUMPSTART 12
  3495. +#define AP121_MINI_GPIO_BTN_RESET 11
  3496. +
  3497. +#ifdef CONFIG_MTD_PARTITIONS
  3498. +static struct mtd_partition ap121_parts[] = {
  3499. + {
  3500. + .name = "u-boot",
  3501. + .offset = 0,
  3502. + .size = 0x010000,
  3503. + .mask_flags = MTD_WRITEABLE,
  3504. + },
  3505. + {
  3506. + .name = "rootfs",
  3507. + .offset = 0x010000,
  3508. + .size = 0x130000,
  3509. + },
  3510. + {
  3511. + .name = "uImage",
  3512. + .offset = 0x140000,
  3513. + .size = 0x0a0000,
  3514. + },
  3515. + {
  3516. + .name = "NVRAM",
  3517. + .offset = 0x1e0000,
  3518. + .size = 0x010000,
  3519. + },
  3520. + {
  3521. + .name = "ART",
  3522. + .offset = 0x1f0000,
  3523. + .size = 0x010000,
  3524. + .mask_flags = MTD_WRITEABLE,
  3525. + },
  3526. +};
  3527. +#define ap121_nr_parts ARRAY_SIZE(ap121_parts)
  3528. +
  3529. +static struct mtd_partition ap121_mini_parts[] = {
  3530. + {
  3531. + .name = "u-boot",
  3532. + .offset = 0,
  3533. + .size = 0x040000,
  3534. + .mask_flags = MTD_WRITEABLE,
  3535. + },
  3536. + {
  3537. + .name = "u-boot-env",
  3538. + .offset = 0x040000,
  3539. + .size = 0x010000,
  3540. + .mask_flags = MTD_WRITEABLE,
  3541. + },
  3542. + {
  3543. + .name = "rootfs",
  3544. + .offset = 0x050000,
  3545. + .size = 0x2b0000,
  3546. + },
  3547. + {
  3548. + .name = "uImage",
  3549. + .offset = 0x300000,
  3550. + .size = 0x0e0000,
  3551. + },
  3552. + {
  3553. + .name = "NVRAM",
  3554. + .offset = 0x3e0000,
  3555. + .size = 0x010000,
  3556. + },
  3557. + {
  3558. + .name = "ART",
  3559. + .offset = 0x3f0000,
  3560. + .size = 0x010000,
  3561. + .mask_flags = MTD_WRITEABLE,
  3562. + },
  3563. +};
  3564. +
  3565. +#define ap121_mini_nr_parts ARRAY_SIZE(ap121_parts)
  3566. +
  3567. +#else
  3568. +#define ap121_parts NULL
  3569. +#define ap121_nr_parts 0
  3570. +#define ap121_mini_parts NULL
  3571. +#define ap121_mini_nr_parts 0
  3572. +#endif /* CONFIG_MTD_PARTITIONS */
  3573. +
  3574. +static struct flash_platform_data ap121_flash_data = {
  3575. + .parts = ap121_parts,
  3576. + .nr_parts = ap121_nr_parts,
  3577. +};
  3578. +
  3579. +static struct gpio_led ap121_leds_gpio[] __initdata = {
  3580. + {
  3581. + .name = "ap121:green:usb",
  3582. + .gpio = AP121_GPIO_LED_USB,
  3583. + .active_low = 0,
  3584. + },
  3585. + {
  3586. + .name = "ap121:green:wlan",
  3587. + .gpio = AP121_GPIO_LED_WLAN,
  3588. + .active_low = 0,
  3589. + },
  3590. +};
  3591. +
  3592. +static struct gpio_keys_button ap121_gpio_keys[] __initdata = {
  3593. + {
  3594. + .desc = "jumpstart button",
  3595. + .type = EV_KEY,
  3596. + .code = KEY_WPS_BUTTON,
  3597. + .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
  3598. + .gpio = AP121_GPIO_BTN_JUMPSTART,
  3599. + .active_low = 1,
  3600. + },
  3601. + {
  3602. + .desc = "reset button",
  3603. + .type = EV_KEY,
  3604. + .code = KEY_RESTART,
  3605. + .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
  3606. + .gpio = AP121_GPIO_BTN_RESET,
  3607. + .active_low = 1,
  3608. + }
  3609. +};
  3610. +
  3611. +static struct gpio_led ap121_mini_leds_gpio[] __initdata = {
  3612. + {
  3613. + .name = "ap121:green:wlan",
  3614. + .gpio = AP121_MINI_GPIO_LED_WLAN,
  3615. + .active_low = 0,
  3616. + },
  3617. +};
  3618. +
  3619. +static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = {
  3620. + {
  3621. + .desc = "jumpstart button",
  3622. + .type = EV_KEY,
  3623. + .code = KEY_WPS_BUTTON,
  3624. + .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
  3625. + .gpio = AP121_MINI_GPIO_BTN_JUMPSTART,
  3626. + .active_low = 1,
  3627. + },
  3628. + {
  3629. + .desc = "reset button",
  3630. + .type = EV_KEY,
  3631. + .code = KEY_RESTART,
  3632. + .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
  3633. + .gpio = AP121_MINI_GPIO_BTN_RESET,
  3634. + .active_low = 1,
  3635. + }
  3636. +};
  3637. +
  3638. +static void __init ap121_common_setup(void)
  3639. +{
  3640. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  3641. +
  3642. + ar71xx_add_device_m25p80(&ap121_flash_data);
  3643. +
  3644. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0);
  3645. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0);
  3646. +
  3647. + /* WAN port */
  3648. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3649. + ar71xx_eth0_data.speed = SPEED_100;
  3650. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3651. + ar71xx_eth0_data.phy_mask = BIT(4);
  3652. +
  3653. + /* LAN ports */
  3654. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3655. + ar71xx_eth1_data.speed = SPEED_1000;
  3656. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  3657. + ar71xx_eth1_data.has_ar7240_switch = 1;
  3658. +
  3659. + ar71xx_add_device_mdio(0x0);
  3660. + ar71xx_add_device_eth(1);
  3661. + ar71xx_add_device_eth(0);
  3662. +
  3663. + ar9xxx_add_device_wmac(art + AP121_CALDATA_OFFSET,
  3664. + art + AP121_WMAC_MAC_OFFSET);
  3665. +}
  3666. +
  3667. +static void __init ap121_setup(void)
  3668. +{
  3669. + ap121_flash_data.parts = ap121_parts;
  3670. + ap121_flash_data.nr_parts = ap121_nr_parts;
  3671. +
  3672. + ap121_common_setup();
  3673. +
  3674. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
  3675. + ap121_leds_gpio);
  3676. + ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
  3677. + ARRAY_SIZE(ap121_gpio_keys),
  3678. + ap121_gpio_keys);
  3679. +
  3680. + ar71xx_add_device_usb();
  3681. +}
  3682. +
  3683. +static void __init ap121_mini_setup(void)
  3684. +{
  3685. + ap121_flash_data.parts = ap121_mini_parts;
  3686. + ap121_flash_data.nr_parts = ap121_mini_nr_parts;
  3687. +
  3688. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio),
  3689. + ap121_mini_leds_gpio);
  3690. + ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
  3691. + ARRAY_SIZE(ap121_mini_gpio_keys),
  3692. + ap121_mini_gpio_keys);
  3693. +
  3694. + ap121_common_setup();
  3695. +}
  3696. +
  3697. +MIPS_MACHINE(AR71XX_MACH_AP121, "AP121", "Atheros AP121",
  3698. + ap121_setup);
  3699. +
  3700. +MIPS_MACHINE(AR71XX_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI",
  3701. + ap121_mini_setup);
  3702. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c
  3703. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100
  3704. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-08-24 18:17:23.000000000 +0200
  3705. @@ -0,0 +1,142 @@
  3706. +/*
  3707. + * Atheros AP81 board support
  3708. + *
  3709. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  3710. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  3711. + *
  3712. + * This program is free software; you can redistribute it and/or modify it
  3713. + * under the terms of the GNU General Public License version 2 as published
  3714. + * by the Free Software Foundation.
  3715. + */
  3716. +
  3717. +#include <linux/mtd/mtd.h>
  3718. +#include <linux/mtd/partitions.h>
  3719. +
  3720. +#include <asm/mach-ar71xx/ar71xx.h>
  3721. +
  3722. +#include "machtype.h"
  3723. +#include "devices.h"
  3724. +#include "dev-m25p80.h"
  3725. +#include "dev-ar9xxx-wmac.h"
  3726. +#include "dev-gpio-buttons.h"
  3727. +#include "dev-leds-gpio.h"
  3728. +#include "dev-usb.h"
  3729. +
  3730. +#define AP81_GPIO_LED_STATUS 1
  3731. +#define AP81_GPIO_LED_AOSS 3
  3732. +#define AP81_GPIO_LED_WLAN 6
  3733. +#define AP81_GPIO_LED_POWER 14
  3734. +
  3735. +#define AP81_GPIO_BTN_SW4 12
  3736. +#define AP81_GPIO_BTN_SW1 21
  3737. +
  3738. +#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
  3739. +#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
  3740. +
  3741. +#ifdef CONFIG_MTD_PARTITIONS
  3742. +static struct mtd_partition ap81_partitions[] = {
  3743. + {
  3744. + .name = "u-boot",
  3745. + .offset = 0,
  3746. + .size = 0x040000,
  3747. + .mask_flags = MTD_WRITEABLE,
  3748. + }, {
  3749. + .name = "u-boot-env",
  3750. + .offset = 0x040000,
  3751. + .size = 0x010000,
  3752. + }, {
  3753. + .name = "rootfs",
  3754. + .offset = 0x050000,
  3755. + .size = 0x500000,
  3756. + }, {
  3757. + .name = "uImage",
  3758. + .offset = 0x550000,
  3759. + .size = 0x100000,
  3760. + }, {
  3761. + .name = "ART",
  3762. + .offset = 0x650000,
  3763. + .size = 0x1b0000,
  3764. + .mask_flags = MTD_WRITEABLE,
  3765. + }
  3766. +};
  3767. +#endif /* CONFIG_MTD_PARTITIONS */
  3768. +
  3769. +static struct flash_platform_data ap81_flash_data = {
  3770. +#ifdef CONFIG_MTD_PARTITIONS
  3771. + .parts = ap81_partitions,
  3772. + .nr_parts = ARRAY_SIZE(ap81_partitions),
  3773. +#endif
  3774. +};
  3775. +
  3776. +static struct gpio_led ap81_leds_gpio[] __initdata = {
  3777. + {
  3778. + .name = "ap81:green:status",
  3779. + .gpio = AP81_GPIO_LED_STATUS,
  3780. + .active_low = 1,
  3781. + }, {
  3782. + .name = "ap81:amber:aoss",
  3783. + .gpio = AP81_GPIO_LED_AOSS,
  3784. + .active_low = 1,
  3785. + }, {
  3786. + .name = "ap81:green:wlan",
  3787. + .gpio = AP81_GPIO_LED_WLAN,
  3788. + .active_low = 1,
  3789. + }, {
  3790. + .name = "ap81:green:power",
  3791. + .gpio = AP81_GPIO_LED_POWER,
  3792. + .active_low = 1,
  3793. + }
  3794. +};
  3795. +
  3796. +static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
  3797. + {
  3798. + .desc = "sw1",
  3799. + .type = EV_KEY,
  3800. + .code = BTN_0,
  3801. + .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
  3802. + .gpio = AP81_GPIO_BTN_SW1,
  3803. + .active_low = 1,
  3804. + }, {
  3805. + .desc = "sw4",
  3806. + .type = EV_KEY,
  3807. + .code = BTN_1,
  3808. + .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
  3809. + .gpio = AP81_GPIO_BTN_SW4,
  3810. + .active_low = 1,
  3811. + }
  3812. +};
  3813. +
  3814. +static void __init ap81_setup(void)
  3815. +{
  3816. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3817. +
  3818. + ar71xx_add_device_mdio(0x0);
  3819. +
  3820. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0);
  3821. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3822. + ar71xx_eth0_data.speed = SPEED_100;
  3823. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3824. + ar71xx_eth0_data.has_ar8216 = 1;
  3825. +
  3826. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1);
  3827. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3828. + ar71xx_eth1_data.phy_mask = 0x10;
  3829. +
  3830. + ar71xx_add_device_eth(0);
  3831. + ar71xx_add_device_eth(1);
  3832. +
  3833. + ar71xx_add_device_usb();
  3834. +
  3835. + ar71xx_add_device_m25p80(&ap81_flash_data);
  3836. +
  3837. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
  3838. + ap81_leds_gpio);
  3839. +
  3840. + ar71xx_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
  3841. + ARRAY_SIZE(ap81_gpio_keys),
  3842. + ap81_gpio_keys);
  3843. +
  3844. + ar9xxx_add_device_wmac(eeprom, NULL);
  3845. +}
  3846. +
  3847. +MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup);
  3848. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c
  3849. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100
  3850. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-08-24 18:17:23.000000000 +0200
  3851. @@ -0,0 +1,267 @@
  3852. +/*
  3853. + * Atheros AP83 board support
  3854. + *
  3855. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3856. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3857. + *
  3858. + * This program is free software; you can redistribute it and/or modify it
  3859. + * under the terms of the GNU General Public License version 2 as published
  3860. + * by the Free Software Foundation.
  3861. + */
  3862. +
  3863. +#include <linux/delay.h>
  3864. +#include <linux/platform_device.h>
  3865. +#include <linux/mtd/mtd.h>
  3866. +#include <linux/mtd/partitions.h>
  3867. +#include <linux/spi/spi.h>
  3868. +#include <linux/spi/spi_gpio.h>
  3869. +#include <linux/spi/vsc7385.h>
  3870. +
  3871. +#include <asm/mach-ar71xx/ar71xx.h>
  3872. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  3873. +
  3874. +#include "machtype.h"
  3875. +#include "devices.h"
  3876. +#include "dev-ar9xxx-wmac.h"
  3877. +#include "dev-gpio-buttons.h"
  3878. +#include "dev-leds-gpio.h"
  3879. +#include "dev-usb.h"
  3880. +
  3881. +#define AP83_GPIO_LED_WLAN 6
  3882. +#define AP83_GPIO_LED_POWER 14
  3883. +#define AP83_GPIO_LED_JUMPSTART 15
  3884. +#define AP83_GPIO_BTN_JUMPSTART 12
  3885. +#define AP83_GPIO_BTN_RESET 21
  3886. +
  3887. +#define AP83_050_GPIO_VSC7385_CS 1
  3888. +#define AP83_050_GPIO_VSC7385_MISO 3
  3889. +#define AP83_050_GPIO_VSC7385_MOSI 16
  3890. +#define AP83_050_GPIO_VSC7385_SCK 17
  3891. +
  3892. +#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */
  3893. +#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL)
  3894. +
  3895. +#ifdef CONFIG_MTD_PARTITIONS
  3896. +static struct mtd_partition ap83_flash_partitions[] = {
  3897. + {
  3898. + .name = "u-boot",
  3899. + .offset = 0,
  3900. + .size = 0x040000,
  3901. + .mask_flags = MTD_WRITEABLE,
  3902. + }, {
  3903. + .name = "u-boot-env",
  3904. + .offset = 0x040000,
  3905. + .size = 0x020000,
  3906. + .mask_flags = MTD_WRITEABLE,
  3907. + }, {
  3908. + .name = "kernel",
  3909. + .offset = 0x060000,
  3910. + .size = 0x140000,
  3911. + }, {
  3912. + .name = "rootfs",
  3913. + .offset = 0x1a0000,
  3914. + .size = 0x650000,
  3915. + }, {
  3916. + .name = "art",
  3917. + .offset = 0x7f0000,
  3918. + .size = 0x010000,
  3919. + .mask_flags = MTD_WRITEABLE,
  3920. + }, {
  3921. + .name = "firmware",
  3922. + .offset = 0x060000,
  3923. + .size = 0x790000,
  3924. + }
  3925. +};
  3926. +#endif /* CONFIG_MTD_PARTITIONS */
  3927. +
  3928. +static struct ar91xx_flash_platform_data ap83_flash_data = {
  3929. + .width = 2,
  3930. +#ifdef CONFIG_MTD_PARTITIONS
  3931. + .parts = ap83_flash_partitions,
  3932. + .nr_parts = ARRAY_SIZE(ap83_flash_partitions),
  3933. +#endif
  3934. +};
  3935. +
  3936. +static struct resource ap83_flash_resources[] = {
  3937. + [0] = {
  3938. + .start = AR71XX_SPI_BASE,
  3939. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3940. + .flags = IORESOURCE_MEM,
  3941. + },
  3942. +};
  3943. +
  3944. +static struct platform_device ap83_flash_device = {
  3945. + .name = "ar91xx-flash",
  3946. + .id = -1,
  3947. + .resource = ap83_flash_resources,
  3948. + .num_resources = ARRAY_SIZE(ap83_flash_resources),
  3949. + .dev = {
  3950. + .platform_data = &ap83_flash_data,
  3951. + }
  3952. +};
  3953. +
  3954. +static struct gpio_led ap83_leds_gpio[] __initdata = {
  3955. + {
  3956. + .name = "ap83:green:jumpstart",
  3957. + .gpio = AP83_GPIO_LED_JUMPSTART,
  3958. + .active_low = 0,
  3959. + }, {
  3960. + .name = "ap83:green:power",
  3961. + .gpio = AP83_GPIO_LED_POWER,
  3962. + .active_low = 0,
  3963. + }, {
  3964. + .name = "ap83:green:wlan",
  3965. + .gpio = AP83_GPIO_LED_WLAN,
  3966. + .active_low = 0,
  3967. + },
  3968. +};
  3969. +
  3970. +static struct gpio_keys_button ap83_gpio_keys[] __initdata = {
  3971. + {
  3972. + .desc = "soft_reset",
  3973. + .type = EV_KEY,
  3974. + .code = KEY_RESTART,
  3975. + .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL,
  3976. + .gpio = AP83_GPIO_BTN_RESET,
  3977. + .active_low = 1,
  3978. + }, {
  3979. + .desc = "jumpstart",
  3980. + .type = EV_KEY,
  3981. + .code = KEY_WPS_BUTTON,
  3982. + .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL,
  3983. + .gpio = AP83_GPIO_BTN_JUMPSTART,
  3984. + .active_low = 1,
  3985. + }
  3986. +};
  3987. +
  3988. +static struct resource ap83_040_spi_resources[] = {
  3989. + [0] = {
  3990. + .start = AR71XX_SPI_BASE,
  3991. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3992. + .flags = IORESOURCE_MEM,
  3993. + },
  3994. +};
  3995. +
  3996. +static struct platform_device ap83_040_spi_device = {
  3997. + .name = "ap83-spi",
  3998. + .id = 0,
  3999. + .resource = ap83_040_spi_resources,
  4000. + .num_resources = ARRAY_SIZE(ap83_040_spi_resources),
  4001. +};
  4002. +
  4003. +static struct spi_gpio_platform_data ap83_050_spi_data = {
  4004. + .miso = AP83_050_GPIO_VSC7385_MISO,
  4005. + .mosi = AP83_050_GPIO_VSC7385_MOSI,
  4006. + .sck = AP83_050_GPIO_VSC7385_SCK,
  4007. + .num_chipselect = 1,
  4008. +};
  4009. +
  4010. +static struct platform_device ap83_050_spi_device = {
  4011. + .name = "spi_gpio",
  4012. + .id = 0,
  4013. + .dev = {
  4014. + .platform_data = &ap83_050_spi_data,
  4015. + }
  4016. +};
  4017. +
  4018. +static void ap83_vsc7385_reset(void)
  4019. +{
  4020. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  4021. + udelay(10);
  4022. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  4023. + mdelay(50);
  4024. +}
  4025. +
  4026. +static struct vsc7385_platform_data ap83_vsc7385_data = {
  4027. + .reset = ap83_vsc7385_reset,
  4028. + .ucode_name = "vsc7385_ucode_ap83.bin",
  4029. + .mac_cfg = {
  4030. + .tx_ipg = 6,
  4031. + .bit2 = 0,
  4032. + .clk_sel = 3,
  4033. + },
  4034. +};
  4035. +
  4036. +static struct spi_board_info ap83_spi_info[] = {
  4037. + {
  4038. + .bus_num = 0,
  4039. + .chip_select = 0,
  4040. + .max_speed_hz = 25000000,
  4041. + .modalias = "spi-vsc7385",
  4042. + .platform_data = &ap83_vsc7385_data,
  4043. + .controller_data = (void *) AP83_050_GPIO_VSC7385_CS,
  4044. + }
  4045. +};
  4046. +
  4047. +static void __init ap83_generic_setup(void)
  4048. +{
  4049. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4050. +
  4051. + ar71xx_add_device_mdio(0xfffffffe);
  4052. +
  4053. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0);
  4054. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4055. + ar71xx_eth0_data.phy_mask = 0x1;
  4056. +
  4057. + ar71xx_add_device_eth(0);
  4058. +
  4059. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1);
  4060. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4061. + ar71xx_eth1_data.speed = SPEED_1000;
  4062. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4063. +
  4064. + ar71xx_eth1_pll_data.pll_1000 = 0x1f000000;
  4065. +
  4066. + ar71xx_add_device_eth(1);
  4067. +
  4068. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
  4069. + ap83_leds_gpio);
  4070. +
  4071. + ar71xx_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL,
  4072. + ARRAY_SIZE(ap83_gpio_keys),
  4073. + ap83_gpio_keys);
  4074. +
  4075. + ar71xx_add_device_usb();
  4076. +
  4077. + ar9xxx_add_device_wmac(eeprom, NULL);
  4078. +
  4079. + platform_device_register(&ap83_flash_device);
  4080. +
  4081. + spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info));
  4082. +}
  4083. +
  4084. +static void __init ap83_040_setup(void)
  4085. +{
  4086. + ap83_flash_data.is_shared = 1;
  4087. + ap83_generic_setup();
  4088. + platform_device_register(&ap83_040_spi_device);
  4089. +}
  4090. +
  4091. +static void __init ap83_050_setup(void)
  4092. +{
  4093. + ap83_generic_setup();
  4094. + platform_device_register(&ap83_050_spi_device);
  4095. +}
  4096. +
  4097. +static void __init ap83_setup(void)
  4098. +{
  4099. + u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244);
  4100. + unsigned int board_version;
  4101. +
  4102. + board_version = (unsigned int)(board_id[0] - '0');
  4103. + board_version += ((unsigned int)(board_id[1] - '0')) * 10;
  4104. +
  4105. + switch (board_version) {
  4106. + case 40:
  4107. + ap83_040_setup();
  4108. + break;
  4109. + case 50:
  4110. + ap83_050_setup();
  4111. + break;
  4112. + default:
  4113. + printk(KERN_WARNING "AP83-%03u board is not yet supported\n",
  4114. + board_version);
  4115. + }
  4116. +}
  4117. +
  4118. +MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup);
  4119. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c linux-2.6.39/arch/mips/ar71xx/mach-ap96.c
  4120. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c 1970-01-01 01:00:00.000000000 +0100
  4121. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap96.c 2011-08-24 18:17:23.000000000 +0200
  4122. @@ -0,0 +1,180 @@
  4123. +/*
  4124. + * Atheros AP96 board support
  4125. + *
  4126. + * Copyright (C) 2009 Marco Porsch
  4127. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  4128. + * Copyright (C) 2010 Atheros Communications
  4129. + *
  4130. + * This program is free software; you can redistribute it and/or modify it
  4131. + * under the terms of the GNU General Public License version 2 as published
  4132. + * by the Free Software Foundation.
  4133. + */
  4134. +
  4135. +#include <linux/platform_device.h>
  4136. +#include <linux/mtd/mtd.h>
  4137. +#include <linux/mtd/partitions.h>
  4138. +#include <linux/delay.h>
  4139. +
  4140. +#include <asm/mach-ar71xx/ar71xx.h>
  4141. +
  4142. +#include "machtype.h"
  4143. +#include "devices.h"
  4144. +#include "dev-m25p80.h"
  4145. +#include "dev-ap94-pci.h"
  4146. +#include "dev-gpio-buttons.h"
  4147. +#include "dev-leds-gpio.h"
  4148. +#include "dev-usb.h"
  4149. +
  4150. +#define AP96_GPIO_LED_12_GREEN 0
  4151. +#define AP96_GPIO_LED_3_GREEN 1
  4152. +#define AP96_GPIO_LED_2_GREEN 2
  4153. +#define AP96_GPIO_LED_WPS_GREEN 4
  4154. +#define AP96_GPIO_LED_5_GREEN 5
  4155. +#define AP96_GPIO_LED_4_ORANGE 6
  4156. +
  4157. +/* Reset button - next to the power connector */
  4158. +#define AP96_GPIO_BTN_RESET 3
  4159. +/* WPS button - next to a led on right */
  4160. +#define AP96_GPIO_BTN_WPS 8
  4161. +
  4162. +#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */
  4163. +#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL)
  4164. +
  4165. +#define AP96_WMAC0_MAC_OFFSET 0x120c
  4166. +#define AP96_WMAC1_MAC_OFFSET 0x520c
  4167. +#define AP96_CALDATA0_OFFSET 0x1000
  4168. +#define AP96_CALDATA1_OFFSET 0x5000
  4169. +
  4170. +#ifdef CONFIG_MTD_PARTITIONS
  4171. +static struct mtd_partition ap96_partitions[] = {
  4172. + {
  4173. + .name = "uboot",
  4174. + .offset = 0,
  4175. + .size = 0x030000,
  4176. + .mask_flags = MTD_WRITEABLE,
  4177. + }, {
  4178. + .name = "env",
  4179. + .offset = 0x030000,
  4180. + .size = 0x010000,
  4181. + .mask_flags = MTD_WRITEABLE,
  4182. + }, {
  4183. + .name = "rootfs",
  4184. + .offset = 0x040000,
  4185. + .size = 0x600000,
  4186. + }, {
  4187. + .name = "uImage",
  4188. + .offset = 0x640000,
  4189. + .size = 0x1b0000,
  4190. + }, {
  4191. + .name = "caldata",
  4192. + .offset = 0x7f0000,
  4193. + .size = 0x010000,
  4194. + .mask_flags = MTD_WRITEABLE,
  4195. + }
  4196. +};
  4197. +#endif /* CONFIG_MTD_PARTITIONS */
  4198. +
  4199. +static struct flash_platform_data ap96_flash_data = {
  4200. +#ifdef CONFIG_MTD_PARTITIONS
  4201. + .parts = ap96_partitions,
  4202. + .nr_parts = ARRAY_SIZE(ap96_partitions),
  4203. +#endif
  4204. +};
  4205. +
  4206. +/*
  4207. + * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12
  4208. + * below (from left to right on the board). Led 1 seems to be on whenever the
  4209. + * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange;
  4210. + * others are green.
  4211. + *
  4212. + * In addition, there is one led next to a button on the right side for WPS.
  4213. + */
  4214. +static struct gpio_led ap96_leds_gpio[] __initdata = {
  4215. + {
  4216. + .name = "ap96:green:led2",
  4217. + .gpio = AP96_GPIO_LED_2_GREEN,
  4218. + .active_low = 1,
  4219. + }, {
  4220. + .name = "ap96:green:led3",
  4221. + .gpio = AP96_GPIO_LED_3_GREEN,
  4222. + .active_low = 1,
  4223. + }, {
  4224. + .name = "ap96:orange:led4",
  4225. + .gpio = AP96_GPIO_LED_4_ORANGE,
  4226. + .active_low = 1,
  4227. + }, {
  4228. + .name = "ap96:green:led5",
  4229. + .gpio = AP96_GPIO_LED_5_GREEN,
  4230. + .active_low = 1,
  4231. + }, {
  4232. + .name = "ap96:green:led12",
  4233. + .gpio = AP96_GPIO_LED_12_GREEN,
  4234. + .active_low = 1,
  4235. + }, { /* next to a button on right */
  4236. + .name = "ap96:green:wps",
  4237. + .gpio = AP96_GPIO_LED_WPS_GREEN,
  4238. + .active_low = 1,
  4239. + }
  4240. +};
  4241. +
  4242. +static struct gpio_keys_button ap96_gpio_keys[] __initdata = {
  4243. + {
  4244. + .desc = "reset",
  4245. + .type = EV_KEY,
  4246. + .code = KEY_RESTART,
  4247. + .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL,
  4248. + .gpio = AP96_GPIO_BTN_RESET,
  4249. + .active_low = 1,
  4250. + }, {
  4251. + .desc = "wps",
  4252. + .type = EV_KEY,
  4253. + .code = KEY_WPS_BUTTON,
  4254. + .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL,
  4255. + .gpio = AP96_GPIO_BTN_WPS,
  4256. + .active_low = 1,
  4257. + }
  4258. +};
  4259. +
  4260. +#define AP96_WAN_PHYMASK 0x10
  4261. +#define AP96_LAN_PHYMASK 0x0f
  4262. +
  4263. +static void __init ap96_setup(void)
  4264. +{
  4265. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  4266. +
  4267. + ar71xx_add_device_mdio(~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK));
  4268. +
  4269. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art, 0);
  4270. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4271. + ar71xx_eth0_data.phy_mask = AP96_LAN_PHYMASK;
  4272. + ar71xx_eth0_data.speed = SPEED_1000;
  4273. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4274. +
  4275. + ar71xx_add_device_eth(0);
  4276. +
  4277. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art, 1);
  4278. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4279. + ar71xx_eth1_data.phy_mask = AP96_WAN_PHYMASK;
  4280. +
  4281. + ar71xx_eth1_pll_data.pll_1000 = 0x1f000000;
  4282. +
  4283. + ar71xx_add_device_eth(1);
  4284. +
  4285. + ar71xx_add_device_usb();
  4286. +
  4287. + ar71xx_add_device_m25p80(&ap96_flash_data);
  4288. +
  4289. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio),
  4290. + ap96_leds_gpio);
  4291. +
  4292. + ar71xx_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL,
  4293. + ARRAY_SIZE(ap96_gpio_keys),
  4294. + ap96_gpio_keys);
  4295. +
  4296. + ap94_pci_init(art + AP96_CALDATA0_OFFSET,
  4297. + art + AP96_WMAC0_MAC_OFFSET,
  4298. + art + AP96_CALDATA1_OFFSET,
  4299. + art + AP96_WMAC1_MAC_OFFSET);
  4300. +}
  4301. +
  4302. +MIPS_MACHINE(AR71XX_MACH_AP96, "AP96", "Atheros AP96", ap96_setup);
  4303. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c
  4304. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100
  4305. +++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-08-24 18:17:23.000000000 +0200
  4306. @@ -0,0 +1,102 @@
  4307. +/*
  4308. + * AzureWave AW-NR580 board support
  4309. + *
  4310. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4311. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4312. + *
  4313. + * This program is free software; you can redistribute it and/or modify it
  4314. + * under the terms of the GNU General Public License version 2 as published
  4315. + * by the Free Software Foundation.
  4316. + */
  4317. +
  4318. +#include <linux/mtd/mtd.h>
  4319. +#include <linux/mtd/partitions.h>
  4320. +
  4321. +#include <asm/mips_machine.h>
  4322. +#include <asm/mach-ar71xx/ar71xx.h>
  4323. +
  4324. +#include "machtype.h"
  4325. +#include "devices.h"
  4326. +#include "dev-m25p80.h"
  4327. +#include "dev-gpio-buttons.h"
  4328. +#include "dev-pb42-pci.h"
  4329. +#include "dev-leds-gpio.h"
  4330. +
  4331. +#define AW_NR580_GPIO_LED_READY_RED 0
  4332. +#define AW_NR580_GPIO_LED_WLAN 1
  4333. +#define AW_NR580_GPIO_LED_READY_GREEN 2
  4334. +#define AW_NR580_GPIO_LED_WPS_GREEN 4
  4335. +#define AW_NR580_GPIO_LED_WPS_AMBER 5
  4336. +
  4337. +#define AW_NR580_GPIO_BTN_WPS 3
  4338. +#define AW_NR580_GPIO_BTN_RESET 11
  4339. +
  4340. +#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */
  4341. +#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL)
  4342. +
  4343. +static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
  4344. + {
  4345. + .name = "aw-nr580:red:ready",
  4346. + .gpio = AW_NR580_GPIO_LED_READY_RED,
  4347. + .active_low = 0,
  4348. + }, {
  4349. + .name = "aw-nr580:green:ready",
  4350. + .gpio = AW_NR580_GPIO_LED_READY_GREEN,
  4351. + .active_low = 0,
  4352. + }, {
  4353. + .name = "aw-nr580:green:wps",
  4354. + .gpio = AW_NR580_GPIO_LED_WPS_GREEN,
  4355. + .active_low = 0,
  4356. + }, {
  4357. + .name = "aw-nr580:amber:wps",
  4358. + .gpio = AW_NR580_GPIO_LED_WPS_AMBER,
  4359. + .active_low = 0,
  4360. + }, {
  4361. + .name = "aw-nr580:green:wlan",
  4362. + .gpio = AW_NR580_GPIO_LED_WLAN,
  4363. + .active_low = 0,
  4364. + }
  4365. +};
  4366. +
  4367. +static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = {
  4368. + {
  4369. + .desc = "reset",
  4370. + .type = EV_KEY,
  4371. + .code = KEY_RESTART,
  4372. + .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL,
  4373. + .gpio = AW_NR580_GPIO_BTN_RESET,
  4374. + .active_low = 1,
  4375. + }, {
  4376. + .desc = "wps",
  4377. + .type = EV_KEY,
  4378. + .code = KEY_WPS_BUTTON,
  4379. + .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL,
  4380. + .gpio = AW_NR580_GPIO_BTN_WPS,
  4381. + .active_low = 1,
  4382. + }
  4383. +};
  4384. +
  4385. +static void __init aw_nr580_setup(void)
  4386. +{
  4387. + ar71xx_add_device_mdio(0x0);
  4388. +
  4389. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  4390. + ar71xx_eth0_data.speed = SPEED_100;
  4391. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4392. +
  4393. + ar71xx_add_device_eth(0);
  4394. +
  4395. + pb42_pci_init();
  4396. +
  4397. + ar71xx_add_device_m25p80(NULL);
  4398. +
  4399. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
  4400. + aw_nr580_leds_gpio);
  4401. +
  4402. + ar71xx_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL,
  4403. + ARRAY_SIZE(aw_nr580_gpio_keys),
  4404. + aw_nr580_gpio_keys);
  4405. +}
  4406. +
  4407. +MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580",
  4408. + aw_nr580_setup);
  4409. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips/ar71xx/mach-db120.c
  4410. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c 1970-01-01 01:00:00.000000000 +0100
  4411. +++ linux-2.6.39/arch/mips/ar71xx/mach-db120.c 2011-08-24 18:17:23.000000000 +0200
  4412. @@ -0,0 +1,134 @@
  4413. +/*
  4414. + * Atheros DB120 board (WASP SoC) support
  4415. + *
  4416. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  4417. + *
  4418. + * This program is free software; you can redistribute it and/or modify it
  4419. + * under the terms of the GNU General Public License version 2 as published
  4420. + * by the Free Software Foundation.
  4421. + */
  4422. +
  4423. +#include <linux/mtd/mtd.h>
  4424. +#include <linux/mtd/partitions.h>
  4425. +
  4426. +#include <asm/mach-ar71xx/ar71xx.h>
  4427. +
  4428. +#include "machtype.h"
  4429. +#include "devices.h"
  4430. +#include "dev-m25p80.h"
  4431. +#include "dev-gpio-buttons.h"
  4432. +#include "dev-leds-gpio.h"
  4433. +#include "dev-usb.h"
  4434. +#include "dev-ar9xxx-wmac.h"
  4435. +#include "dev-db120-pci.h"
  4436. +
  4437. +#define DB120_GPIO_LED_USB 11
  4438. +#define DB120_GPIO_LED_WLAN_5G 12
  4439. +#define DB120_GPIO_LED_WLAN_2G 13
  4440. +#define DB120_GPIO_LED_STATUS 14
  4441. +#define DB120_GPIO_LED_WPS 15
  4442. +
  4443. +#define DB120_GPIO_BTN_SW1 16
  4444. +
  4445. +#define DB120_CALDATA_OFFSET 0x1000
  4446. +#define DB120_WMAC_MAC_OFFSET 0x1002
  4447. +
  4448. +#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
  4449. +#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
  4450. +
  4451. +#ifdef CONFIG_MTD_PARTITIONS
  4452. +static struct mtd_partition db120_partitions[] = {
  4453. + {
  4454. + .name = "u-boot",
  4455. + .offset = 0,
  4456. + .size = 0x040000,
  4457. + .mask_flags = MTD_WRITEABLE,
  4458. + }, {
  4459. + .name = "u-boot-env",
  4460. + .offset = 0x040000,
  4461. + .size = 0x010000,
  4462. + }, {
  4463. + .name = "rootfs",
  4464. + .offset = 0x050000,
  4465. + .size = 0x630000,
  4466. + }, {
  4467. + .name = "uImage",
  4468. + .offset = 0x680000,
  4469. + .size = 0x160000,
  4470. + }, {
  4471. + .name = "NVRAM",
  4472. + .offset = 0x7E0000,
  4473. + .size = 0x010000,
  4474. + }, {
  4475. + .name = "ART",
  4476. + .offset = 0x7F0000,
  4477. + .size = 0x010000,
  4478. + .mask_flags = MTD_WRITEABLE,
  4479. + }
  4480. +};
  4481. +#endif /* CONFIG_MTD_PARTITIONS */
  4482. +
  4483. +static struct flash_platform_data db120_flash_data = {
  4484. +#ifdef CONFIG_MTD_PARTITIONS
  4485. + .parts = db120_partitions,
  4486. + .nr_parts = ARRAY_SIZE(db120_partitions),
  4487. +#endif
  4488. +};
  4489. +
  4490. +static struct gpio_led db120_leds_gpio[] __initdata = {
  4491. + {
  4492. + .name = "db120:green:status",
  4493. + .gpio = DB120_GPIO_LED_STATUS,
  4494. + .active_low = 1,
  4495. + }, {
  4496. + .name = "db120:green:wps",
  4497. + .gpio = DB120_GPIO_LED_WPS,
  4498. + .active_low = 1,
  4499. + }, {
  4500. + .name = "db120:green:wlan-5g",
  4501. + .gpio = DB120_GPIO_LED_WLAN_5G,
  4502. + .active_low = 1,
  4503. + }, {
  4504. + .name = "db120:green:wlan-2g",
  4505. + .gpio = DB120_GPIO_LED_WLAN_2G,
  4506. + .active_low = 1,
  4507. + }, {
  4508. + .name = "db120:green:usb",
  4509. + .gpio = DB120_GPIO_LED_USB,
  4510. + .active_low = 1,
  4511. + }
  4512. +};
  4513. +
  4514. +static struct gpio_keys_button db120_gpio_keys[] __initdata = {
  4515. + {
  4516. + .desc = "sw1",
  4517. + .type = EV_KEY,
  4518. + .code = BTN_0,
  4519. + .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
  4520. + .gpio = DB120_GPIO_BTN_SW1,
  4521. + .active_low = 1,
  4522. + }
  4523. +};
  4524. +
  4525. +static void __init db120_setup(void)
  4526. +{
  4527. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  4528. +
  4529. + ar71xx_add_device_usb();
  4530. +
  4531. + ar71xx_add_device_m25p80(&db120_flash_data);
  4532. +
  4533. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
  4534. + db120_leds_gpio);
  4535. +
  4536. + ar71xx_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
  4537. + ARRAY_SIZE(db120_gpio_keys),
  4538. + db120_gpio_keys);
  4539. +
  4540. + ar9xxx_add_device_wmac(art + DB120_CALDATA_OFFSET,
  4541. + art + DB120_WMAC_MAC_OFFSET);
  4542. +
  4543. + db120_pci_init();
  4544. +}
  4545. +
  4546. +MIPS_MACHINE(AR71XX_MACH_DB120, "DB120", "Atheros DB120", db120_setup);
  4547. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c
  4548. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100
  4549. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-08-24 18:17:23.000000000 +0200
  4550. @@ -0,0 +1,159 @@
  4551. +/*
  4552. + * D-Link DIR-600 rev. A1 board support
  4553. + *
  4554. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  4555. + *
  4556. + * This program is free software; you can redistribute it and/or modify it
  4557. + * under the terms of the GNU General Public License version 2 as published
  4558. + * by the Free Software Foundation.
  4559. + */
  4560. +
  4561. +#include <linux/mtd/mtd.h>
  4562. +#include <linux/mtd/partitions.h>
  4563. +
  4564. +#include <asm/mach-ar71xx/ar71xx.h>
  4565. +
  4566. +#include "machtype.h"
  4567. +#include "devices.h"
  4568. +#include "dev-m25p80.h"
  4569. +#include "dev-ap91-pci.h"
  4570. +#include "dev-gpio-buttons.h"
  4571. +#include "dev-leds-gpio.h"
  4572. +#include "nvram.h"
  4573. +
  4574. +#define DIR_600_A1_GPIO_LED_WPS 0
  4575. +#define DIR_600_A1_GPIO_LED_POWER_AMBER 1
  4576. +#define DIR_600_A1_GPIO_LED_POWER_GREEN 6
  4577. +
  4578. +#define DIR_600_A1_GPIO_BTN_RESET 8
  4579. +#define DIR_600_A1_GPIO_BTN_WPS 12
  4580. +
  4581. +#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */
  4582. +#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL)
  4583. +
  4584. +#define DIR_600_A1_NVRAM_ADDR 0x1f030000
  4585. +#define DIR_600_A1_NVRAM_SIZE 0x10000
  4586. +
  4587. +#ifdef CONFIG_MTD_PARTITIONS
  4588. +static struct mtd_partition dir_600_a1_partitions[] = {
  4589. + {
  4590. + .name = "u-boot",
  4591. + .offset = 0,
  4592. + .size = 0x030000,
  4593. + .mask_flags = MTD_WRITEABLE,
  4594. + }, {
  4595. + .name = "nvram",
  4596. + .offset = 0x030000,
  4597. + .size = 0x010000,
  4598. + }, {
  4599. + .name = "kernel",
  4600. + .offset = 0x040000,
  4601. + .size = 0x0e0000,
  4602. + }, {
  4603. + .name = "rootfs",
  4604. + .offset = 0x120000,
  4605. + .size = 0x2c0000,
  4606. + }, {
  4607. + .name = "mac",
  4608. + .offset = 0x3e0000,
  4609. + .size = 0x010000,
  4610. + .mask_flags = MTD_WRITEABLE,
  4611. + }, {
  4612. + .name = "art",
  4613. + .offset = 0x3f0000,
  4614. + .size = 0x010000,
  4615. + .mask_flags = MTD_WRITEABLE,
  4616. + }, {
  4617. + .name = "firmware",
  4618. + .offset = 0x040000,
  4619. + .size = 0x3a0000,
  4620. + }
  4621. +};
  4622. +#endif /* CONFIG_MTD_PARTITIONS */
  4623. +
  4624. +static struct flash_platform_data dir_600_a1_flash_data = {
  4625. +#ifdef CONFIG_MTD_PARTITIONS
  4626. + .parts = dir_600_a1_partitions,
  4627. + .nr_parts = ARRAY_SIZE(dir_600_a1_partitions),
  4628. +#endif
  4629. +};
  4630. +
  4631. +static struct gpio_led dir_600_a1_leds_gpio[] __initdata = {
  4632. + {
  4633. + .name = "dir-600-a1:green:power",
  4634. + .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN,
  4635. + }, {
  4636. + .name = "dir-600-a1:amber:power",
  4637. + .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER,
  4638. + }, {
  4639. + .name = "dir-600-a1:blue:wps",
  4640. + .gpio = DIR_600_A1_GPIO_LED_WPS,
  4641. + .active_low = 1,
  4642. + }
  4643. +};
  4644. +
  4645. +static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = {
  4646. + {
  4647. + .desc = "reset",
  4648. + .type = EV_KEY,
  4649. + .code = KEY_RESTART,
  4650. + .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL,
  4651. + .gpio = DIR_600_A1_GPIO_BTN_RESET,
  4652. + .active_low = 1,
  4653. + }, {
  4654. + .desc = "wps",
  4655. + .type = EV_KEY,
  4656. + .code = KEY_WPS_BUTTON,
  4657. + .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL,
  4658. + .gpio = DIR_600_A1_GPIO_BTN_WPS,
  4659. + .active_low = 1,
  4660. + }
  4661. +};
  4662. +
  4663. +static void __init dir_600_a1_setup(void)
  4664. +{
  4665. + const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR);
  4666. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  4667. + u8 mac_buff[6];
  4668. + u8 *mac = NULL;
  4669. +
  4670. + if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE,
  4671. + "lan_mac=", mac_buff) == 0) {
  4672. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac_buff, 0);
  4673. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_buff, 1);
  4674. + mac = mac_buff;
  4675. + }
  4676. +
  4677. + ar71xx_add_device_m25p80(&dir_600_a1_flash_data);
  4678. +
  4679. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio),
  4680. + dir_600_a1_leds_gpio);
  4681. +
  4682. + ar71xx_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL,
  4683. + ARRAY_SIZE(dir_600_a1_gpio_keys),
  4684. + dir_600_a1_gpio_keys);
  4685. +
  4686. + ar71xx_eth1_data.has_ar7240_switch = 1;
  4687. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  4688. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  4689. +
  4690. + /* WAN port */
  4691. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4692. + ar71xx_eth0_data.speed = SPEED_100;
  4693. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4694. + ar71xx_eth0_data.phy_mask = BIT(4);
  4695. +
  4696. + /* LAN ports */
  4697. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4698. + ar71xx_eth1_data.speed = SPEED_1000;
  4699. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4700. +
  4701. + ar71xx_add_device_mdio(0x0);
  4702. + ar71xx_add_device_eth(1);
  4703. + ar71xx_add_device_eth(0);
  4704. +
  4705. + ap91_pci_init(ee, mac);
  4706. +}
  4707. +
  4708. +MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1",
  4709. + dir_600_a1_setup);
  4710. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c
  4711. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100
  4712. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-08-24 18:17:23.000000000 +0200
  4713. @@ -0,0 +1,175 @@
  4714. +/*
  4715. + * D-Link DIR-615 rev C1 board support
  4716. + *
  4717. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4718. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4719. + *
  4720. + * This program is free software; you can redistribute it and/or modify it
  4721. + * under the terms of the GNU General Public License version 2 as published
  4722. + * by the Free Software Foundation.
  4723. + */
  4724. +
  4725. +#include <linux/mtd/mtd.h>
  4726. +#include <linux/mtd/partitions.h>
  4727. +
  4728. +#include <asm/mach-ar71xx/ar71xx.h>
  4729. +
  4730. +#include "machtype.h"
  4731. +#include "devices.h"
  4732. +#include "dev-m25p80.h"
  4733. +#include "dev-ar9xxx-wmac.h"
  4734. +#include "dev-gpio-buttons.h"
  4735. +#include "dev-leds-gpio.h"
  4736. +#include "nvram.h"
  4737. +
  4738. +#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */
  4739. +#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */
  4740. +#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */
  4741. +#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */
  4742. +#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */
  4743. +#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */
  4744. +#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */
  4745. +
  4746. +/* buttons may need refinement */
  4747. +
  4748. +#define DIR_615C1_GPIO_BTN_WPS 12
  4749. +#define DIR_615C1_GPIO_BTN_RESET 21
  4750. +
  4751. +#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */
  4752. +#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL)
  4753. +
  4754. +#define DIR_615C1_CONFIG_ADDR 0x1f020000
  4755. +#define DIR_615C1_CONFIG_SIZE 0x10000
  4756. +
  4757. +#ifdef CONFIG_MTD_PARTITIONS
  4758. +static struct mtd_partition dir_615c1_partitions[] = {
  4759. + {
  4760. + .name = "u-boot",
  4761. + .offset = 0,
  4762. + .size = 0x020000,
  4763. + .mask_flags = MTD_WRITEABLE,
  4764. + }, {
  4765. + .name = "config",
  4766. + .offset = 0x020000,
  4767. + .size = 0x010000,
  4768. + }, {
  4769. + .name = "kernel",
  4770. + .offset = 0x030000,
  4771. + .size = 0x0e0000,
  4772. + }, {
  4773. + .name = "rootfs",
  4774. + .offset = 0x110000,
  4775. + .size = 0x2e0000,
  4776. + }, {
  4777. + .name = "art",
  4778. + .offset = 0x3f0000,
  4779. + .size = 0x010000,
  4780. + .mask_flags = MTD_WRITEABLE,
  4781. + }, {
  4782. + .name = "firmware",
  4783. + .offset = 0x030000,
  4784. + .size = 0x3c0000,
  4785. + }
  4786. +};
  4787. +#endif /* CONFIG_MTD_PARTITIONS */
  4788. +
  4789. +static struct flash_platform_data dir_615c1_flash_data = {
  4790. +#ifdef CONFIG_MTD_PARTITIONS
  4791. + .parts = dir_615c1_partitions,
  4792. + .nr_parts = ARRAY_SIZE(dir_615c1_partitions),
  4793. +#endif
  4794. +};
  4795. +
  4796. +static struct gpio_led dir_615c1_leds_gpio[] __initdata = {
  4797. + {
  4798. + .name = "dir-615c1:orange:status",
  4799. + .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS,
  4800. + .active_low = 1,
  4801. + }, {
  4802. + .name = "dir-615c1:blue:wps",
  4803. + .gpio = DIR_615C1_GPIO_LED_BLUE_WPS,
  4804. + .active_low = 1,
  4805. + }, {
  4806. + .name = "dir-615c1:green:wan",
  4807. + .gpio = DIR_615C1_GPIO_LED_GREEN_WAN,
  4808. + .active_low = 1,
  4809. + }, {
  4810. + .name = "dir-615c1:green:wancpu",
  4811. + .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU,
  4812. + .active_low = 1,
  4813. + }, {
  4814. + .name = "dir-615c1:green:wlan",
  4815. + .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN,
  4816. + .active_low = 1,
  4817. + }, {
  4818. + .name = "dir-615c1:green:status",
  4819. + .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS,
  4820. + .active_low = 1,
  4821. + }, {
  4822. + .name = "dir-615c1:orange:wan",
  4823. + .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN,
  4824. + .active_low = 1,
  4825. + }
  4826. +
  4827. +};
  4828. +
  4829. +static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = {
  4830. + {
  4831. + .desc = "reset",
  4832. + .type = EV_KEY,
  4833. + .code = KEY_RESTART,
  4834. + .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL,
  4835. + .gpio = DIR_615C1_GPIO_BTN_RESET,
  4836. + }, {
  4837. + .desc = "wps",
  4838. + .type = EV_KEY,
  4839. + .code = KEY_WPS_BUTTON,
  4840. + .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL,
  4841. + .gpio = DIR_615C1_GPIO_BTN_WPS,
  4842. + }
  4843. +};
  4844. +
  4845. +#define DIR_615C1_LAN_PHYMASK BIT(0)
  4846. +#define DIR_615C1_WAN_PHYMASK BIT(4)
  4847. +#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \
  4848. + DIR_615C1_WAN_PHYMASK))
  4849. +
  4850. +static void __init dir_615c1_setup(void)
  4851. +{
  4852. + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR);
  4853. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4854. + u8 mac[6];
  4855. + u8 *wlan_mac = NULL;
  4856. +
  4857. + if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE,
  4858. + "lan_mac=", mac) == 0) {
  4859. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  4860. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  4861. + wlan_mac = mac;
  4862. + }
  4863. +
  4864. + ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK);
  4865. +
  4866. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4867. + ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK;
  4868. +
  4869. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4870. + ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK;
  4871. +
  4872. + ar71xx_add_device_eth(0);
  4873. + ar71xx_add_device_eth(1);
  4874. +
  4875. + ar71xx_add_device_m25p80(&dir_615c1_flash_data);
  4876. +
  4877. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio),
  4878. + dir_615c1_leds_gpio);
  4879. +
  4880. + ar71xx_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL,
  4881. + ARRAY_SIZE(dir_615c1_gpio_keys),
  4882. + dir_615c1_gpio_keys);
  4883. +
  4884. + ar9xxx_add_device_wmac(eeprom, wlan_mac);
  4885. +}
  4886. +
  4887. +MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1",
  4888. + dir_615c1_setup);
  4889. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c
  4890. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100
  4891. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-08-24 18:17:23.000000000 +0200
  4892. @@ -0,0 +1,198 @@
  4893. +/*
  4894. + * D-Link DIR-825 rev. B1 board support
  4895. + *
  4896. + * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o.
  4897. + *
  4898. + * based on mach-wndr3700.c
  4899. + *
  4900. + * This program is free software; you can redistribute it and/or modify it
  4901. + * under the terms of the GNU General Public License version 2 as published
  4902. + * by the Free Software Foundation.
  4903. + */
  4904. +
  4905. +#include <linux/platform_device.h>
  4906. +#include <linux/mtd/mtd.h>
  4907. +#include <linux/mtd/partitions.h>
  4908. +#include <linux/delay.h>
  4909. +#include <linux/rtl8366.h>
  4910. +
  4911. +#include <asm/mach-ar71xx/ar71xx.h>
  4912. +
  4913. +#include "machtype.h"
  4914. +#include "devices.h"
  4915. +#include "dev-m25p80.h"
  4916. +#include "dev-ap94-pci.h"
  4917. +#include "dev-gpio-buttons.h"
  4918. +#include "dev-leds-gpio.h"
  4919. +#include "dev-usb.h"
  4920. +
  4921. +#define DIR825B1_GPIO_LED_BLUE_USB 0
  4922. +#define DIR825B1_GPIO_LED_ORANGE_POWER 1
  4923. +#define DIR825B1_GPIO_LED_BLUE_POWER 2
  4924. +#define DIR825B1_GPIO_LED_BLUE_WPS 4
  4925. +#define DIR825B1_GPIO_LED_ORANGE_PLANET 6
  4926. +#define DIR825B1_GPIO_LED_BLUE_PLANET 11
  4927. +
  4928. +#define DIR825B1_GPIO_BTN_RESET 3
  4929. +#define DIR825B1_GPIO_BTN_WPS 8
  4930. +
  4931. +#define DIR825B1_GPIO_RTL8366_SDA 5
  4932. +#define DIR825B1_GPIO_RTL8366_SCK 7
  4933. +
  4934. +#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */
  4935. +#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL)
  4936. +
  4937. +#define DIR825B1_CAL_LOCATION_0 0x1f661000
  4938. +#define DIR825B1_CAL_LOCATION_1 0x1f665000
  4939. +
  4940. +#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8
  4941. +#define DIR825B1_MAC_LOCATION_1 0x2ffa8370
  4942. +
  4943. +#ifdef CONFIG_MTD_PARTITIONS
  4944. +static struct mtd_partition dir825b1_partitions[] = {
  4945. + {
  4946. + .name = "uboot",
  4947. + .offset = 0,
  4948. + .size = 0x040000,
  4949. + .mask_flags = MTD_WRITEABLE,
  4950. + }, {
  4951. + .name = "config",
  4952. + .offset = 0x040000,
  4953. + .size = 0x010000,
  4954. + .mask_flags = MTD_WRITEABLE,
  4955. + }, {
  4956. + .name = "firmware",
  4957. + .offset = 0x050000,
  4958. + .size = 0x610000,
  4959. + }, {
  4960. + .name = "caldata",
  4961. + .offset = 0x660000,
  4962. + .size = 0x010000,
  4963. + .mask_flags = MTD_WRITEABLE,
  4964. + }, {
  4965. + .name = "unknown",
  4966. + .offset = 0x670000,
  4967. + .size = 0x190000,
  4968. + .mask_flags = MTD_WRITEABLE,
  4969. + }
  4970. +};
  4971. +#endif /* CONFIG_MTD_PARTITIONS */
  4972. +
  4973. +static struct flash_platform_data dir825b1_flash_data = {
  4974. +#ifdef CONFIG_MTD_PARTITIONS
  4975. + .parts = dir825b1_partitions,
  4976. + .nr_parts = ARRAY_SIZE(dir825b1_partitions),
  4977. +#endif
  4978. +};
  4979. +
  4980. +static struct gpio_led dir825b1_leds_gpio[] __initdata = {
  4981. + {
  4982. + .name = "dir825b1:blue:usb",
  4983. + .gpio = DIR825B1_GPIO_LED_BLUE_USB,
  4984. + .active_low = 1,
  4985. + }, {
  4986. + .name = "dir825b1:orange:power",
  4987. + .gpio = DIR825B1_GPIO_LED_ORANGE_POWER,
  4988. + .active_low = 1,
  4989. + }, {
  4990. + .name = "dir825b1:blue:power",
  4991. + .gpio = DIR825B1_GPIO_LED_BLUE_POWER,
  4992. + .active_low = 1,
  4993. + }, {
  4994. + .name = "dir825b1:blue:wps",
  4995. + .gpio = DIR825B1_GPIO_LED_BLUE_WPS,
  4996. + .active_low = 1,
  4997. + }, {
  4998. + .name = "dir825b1:orange:planet",
  4999. + .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET,
  5000. + .active_low = 1,
  5001. + }, {
  5002. + .name = "dir825b1:blue:planet",
  5003. + .gpio = DIR825B1_GPIO_LED_BLUE_PLANET,
  5004. + .active_low = 1,
  5005. + }
  5006. +};
  5007. +
  5008. +static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = {
  5009. + {
  5010. + .desc = "reset",
  5011. + .type = EV_KEY,
  5012. + .code = KEY_RESTART,
  5013. + .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL,
  5014. + .gpio = DIR825B1_GPIO_BTN_RESET,
  5015. + .active_low = 1,
  5016. + }, {
  5017. + .desc = "wps",
  5018. + .type = EV_KEY,
  5019. + .code = KEY_WPS_BUTTON,
  5020. + .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL,
  5021. + .gpio = DIR825B1_GPIO_BTN_WPS,
  5022. + .active_low = 1,
  5023. + }
  5024. +};
  5025. +
  5026. +static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = {
  5027. + { .reg = 0x06, .val = 0x0108 },
  5028. +};
  5029. +
  5030. +static struct rtl8366_platform_data dir825b1_rtl8366s_data = {
  5031. + .gpio_sda = DIR825B1_GPIO_RTL8366_SDA,
  5032. + .gpio_sck = DIR825B1_GPIO_RTL8366_SCK,
  5033. + .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals),
  5034. + .initvals = dir825b1_rtl8366s_initvals,
  5035. +};
  5036. +
  5037. +static struct platform_device dir825b1_rtl8366s_device = {
  5038. + .name = RTL8366S_DRIVER_NAME,
  5039. + .id = -1,
  5040. + .dev = {
  5041. + .platform_data = &dir825b1_rtl8366s_data,
  5042. + }
  5043. +};
  5044. +
  5045. +static void __init dir825b1_setup(void)
  5046. +{
  5047. + u8 *mac = (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1);
  5048. +
  5049. + ar71xx_add_device_mdio(0x0);
  5050. +
  5051. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1);
  5052. + ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  5053. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5054. + ar71xx_eth0_data.speed = SPEED_1000;
  5055. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5056. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  5057. +
  5058. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2);
  5059. + ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  5060. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5061. + ar71xx_eth1_data.phy_mask = 0x10;
  5062. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  5063. +
  5064. + ar71xx_add_device_eth(0);
  5065. + ar71xx_add_device_eth(1);
  5066. +
  5067. + ar71xx_add_device_m25p80(&dir825b1_flash_data);
  5068. +
  5069. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio),
  5070. + dir825b1_leds_gpio);
  5071. +
  5072. + ar71xx_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL,
  5073. + ARRAY_SIZE(dir825b1_gpio_keys),
  5074. + dir825b1_gpio_keys);
  5075. +
  5076. + ar71xx_add_device_usb();
  5077. +
  5078. + platform_device_register(&dir825b1_rtl8366s_device);
  5079. +
  5080. + ap94_pci_setup_wmac_led_pin(0, 5);
  5081. + ap94_pci_setup_wmac_led_pin(1, 5);
  5082. +
  5083. + ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0),
  5084. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0),
  5085. + (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1),
  5086. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1));
  5087. +}
  5088. +
  5089. +MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1",
  5090. + dir825b1_setup);
  5091. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c
  5092. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c 1970-01-01 01:00:00.000000000 +0100
  5093. +++ linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c 2011-08-24 18:17:23.000000000 +0200
  5094. @@ -0,0 +1,180 @@
  5095. +/*
  5096. + * Senao EAP7660D board support
  5097. + *
  5098. + * Copyright (C) 2010 Daniel Golle <daniel.golle@gmail.com>
  5099. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  5100. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5101. + *
  5102. + * This program is free software; you can redistribute it and/or modify it
  5103. + * under the terms of the GNU General Public License version 2 as published
  5104. + * by the Free Software Foundation.
  5105. + */
  5106. +
  5107. +#include <linux/pci.h>
  5108. +#include <linux/ath5k_platform.h>
  5109. +#include <linux/delay.h>
  5110. +#include <asm/mach-ar71xx/ar71xx.h>
  5111. +#include <asm/mach-ar71xx/pci.h>
  5112. +
  5113. +#include "machtype.h"
  5114. +#include "devices.h"
  5115. +#include "dev-gpio-buttons.h"
  5116. +#include "dev-leds-gpio.h"
  5117. +#include "dev-m25p80.h"
  5118. +
  5119. +#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */
  5120. +#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL)
  5121. +
  5122. +#define EAP7660D_GPIO_DS4 7
  5123. +#define EAP7660D_GPIO_DS5 2
  5124. +#define EAP7660D_GPIO_DS7 0
  5125. +#define EAP7660D_GPIO_DS8 4
  5126. +#define EAP7660D_GPIO_SW1 3
  5127. +#define EAP7660D_GPIO_SW3 8
  5128. +#define EAP7660D_PHYMASK BIT(20)
  5129. +#define EAP7660D_BOARDCONFIG 0x1F7F0000
  5130. +#define EAP7660D_GBIC_MAC_OFFSET 0x1000
  5131. +#define EAP7660D_WMAC0_MAC_OFFSET 0x1010
  5132. +#define EAP7660D_WMAC1_MAC_OFFSET 0x1016
  5133. +#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000
  5134. +#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000
  5135. +
  5136. +static struct ath5k_platform_data eap7660d_wmac0_data;
  5137. +static struct ath5k_platform_data eap7660d_wmac1_data;
  5138. +static char eap7660d_wmac0_mac[6];
  5139. +static char eap7660d_wmac1_mac[6];
  5140. +static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS];
  5141. +static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS];
  5142. +
  5143. +#ifdef CONFIG_PCI
  5144. +static struct ar71xx_pci_irq eap7660d_pci_irqs[] __initdata = {
  5145. + {
  5146. + .slot = 0,
  5147. + .pin = 1,
  5148. + .irq = AR71XX_PCI_IRQ_DEV0,
  5149. + }, {
  5150. + .slot = 1,
  5151. + .pin = 1,
  5152. + .irq = AR71XX_PCI_IRQ_DEV1,
  5153. + }
  5154. +};
  5155. +
  5156. +static int eap7660d_pci_plat_dev_init(struct pci_dev *dev)
  5157. +{
  5158. + switch (PCI_SLOT(dev->devfn)) {
  5159. + case 17:
  5160. + dev->dev.platform_data = &eap7660d_wmac0_data;
  5161. + break;
  5162. +
  5163. + case 18:
  5164. + dev->dev.platform_data = &eap7660d_wmac1_data;
  5165. + break;
  5166. + }
  5167. +
  5168. + return 0;
  5169. +}
  5170. +
  5171. +void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0,
  5172. + u8 *cal_data1, u8 *mac_addr1)
  5173. +{
  5174. + if (cal_data0 && *cal_data0 == 0xa55a) {
  5175. + memcpy(eap7660d_wmac0_eeprom, cal_data0,
  5176. + ATH5K_PLAT_EEP_MAX_WORDS);
  5177. + eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom;
  5178. + }
  5179. +
  5180. + if (cal_data1 && *cal_data1 == 0xa55a) {
  5181. + memcpy(eap7660d_wmac1_eeprom, cal_data1,
  5182. + ATH5K_PLAT_EEP_MAX_WORDS);
  5183. + eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom;
  5184. + }
  5185. +
  5186. + if (mac_addr0) {
  5187. + memcpy(eap7660d_wmac0_mac, mac_addr0,
  5188. + sizeof(eap7660d_wmac0_mac));
  5189. + eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac;
  5190. + }
  5191. +
  5192. + if (mac_addr1) {
  5193. + memcpy(eap7660d_wmac1_mac, mac_addr1,
  5194. + sizeof(eap7660d_wmac1_mac));
  5195. + eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac;
  5196. + }
  5197. +
  5198. + ar71xx_pci_plat_dev_init = eap7660d_pci_plat_dev_init;
  5199. + ar71xx_pci_init(ARRAY_SIZE(eap7660d_pci_irqs), eap7660d_pci_irqs);
  5200. +}
  5201. +#else
  5202. +static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0,
  5203. + u8 *cal_data1, u8 *mac_addr1)
  5204. +{
  5205. +}
  5206. +#endif /* CONFIG_PCI */
  5207. +
  5208. +static struct gpio_led eap7660d_leds_gpio[] __initdata = {
  5209. + {
  5210. + .name = "eap7660d:green:ds8",
  5211. + .gpio = EAP7660D_GPIO_DS8,
  5212. + .active_low = 0,
  5213. + },
  5214. + {
  5215. + .name = "eap7660d:green:ds5",
  5216. + .gpio = EAP7660D_GPIO_DS5,
  5217. + .active_low = 0,
  5218. + },
  5219. + {
  5220. + .name = "eap7660d:green:ds7",
  5221. + .gpio = EAP7660D_GPIO_DS7,
  5222. + .active_low = 0,
  5223. + },
  5224. + {
  5225. + .name = "eap7660d:green:ds4",
  5226. + .gpio = EAP7660D_GPIO_DS4,
  5227. + .active_low = 0,
  5228. + }
  5229. +};
  5230. +
  5231. +static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = {
  5232. + {
  5233. + .desc = "reset",
  5234. + .type = EV_KEY,
  5235. + .code = KEY_RESTART,
  5236. + .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL,
  5237. + .gpio = EAP7660D_GPIO_SW1,
  5238. + .active_low = 1,
  5239. + },
  5240. + {
  5241. + .desc = "wps",
  5242. + .type = EV_KEY,
  5243. + .code = KEY_WPS_BUTTON,
  5244. + .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL,
  5245. + .gpio = EAP7660D_GPIO_SW3,
  5246. + .active_low = 1,
  5247. + }
  5248. +};
  5249. +
  5250. +static void __init eap7660d_setup(void)
  5251. +{
  5252. + u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG);
  5253. +
  5254. + ar71xx_add_device_mdio(~EAP7660D_PHYMASK);
  5255. +
  5256. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr,
  5257. + boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0);
  5258. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5259. + ar71xx_eth0_data.phy_mask = EAP7660D_PHYMASK;
  5260. + ar71xx_add_device_eth(0);
  5261. + ar71xx_add_device_m25p80(NULL);
  5262. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio),
  5263. + eap7660d_leds_gpio);
  5264. + ar71xx_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL,
  5265. + ARRAY_SIZE(eap7660d_gpio_keys),
  5266. + eap7660d_gpio_keys);
  5267. + eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET,
  5268. + boardconfig + EAP7660D_WMAC0_MAC_OFFSET,
  5269. + boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET,
  5270. + boardconfig + EAP7660D_WMAC1_MAC_OFFSET);
  5271. +};
  5272. +
  5273. +MIPS_MACHINE(AR71XX_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D",
  5274. + eap7660d_setup);
  5275. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c
  5276. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c 1970-01-01 01:00:00.000000000 +0100
  5277. +++ linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c 2011-08-24 18:17:23.000000000 +0200
  5278. @@ -0,0 +1,102 @@
  5279. +/*
  5280. + * jjPlus JA76PF board support
  5281. + */
  5282. +
  5283. +#include <asm/mach-ar71xx/ar71xx.h>
  5284. +#include <linux/platform_device.h>
  5285. +#include <linux/i2c.h>
  5286. +#include <linux/i2c-gpio.h>
  5287. +
  5288. +#include "machtype.h"
  5289. +#include "devices.h"
  5290. +#include "dev-m25p80.h"
  5291. +#include "dev-gpio-buttons.h"
  5292. +#include "dev-pb42-pci.h"
  5293. +#include "dev-usb.h"
  5294. +#include "dev-leds-gpio.h"
  5295. +
  5296. +#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */
  5297. +#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL)
  5298. +
  5299. +#define JA76PF_GPIO_I2C_SCL 0
  5300. +#define JA76PF_GPIO_I2C_SDA 1
  5301. +#define JA76PF_GPIO_LED_1 5
  5302. +#define JA76PF_GPIO_LED_2 4
  5303. +#define JA76PF_GPIO_LED_3 3
  5304. +#define JA76PF_GPIO_BTN_RESET 11
  5305. +
  5306. +static struct gpio_led ja76pf_leds_gpio[] __initdata = {
  5307. + {
  5308. + .name = "ja76pf:green:led1",
  5309. + .gpio = JA76PF_GPIO_LED_1,
  5310. + .active_low = 1,
  5311. + }, {
  5312. + .name = "ja76pf:green:led2",
  5313. + .gpio = JA76PF_GPIO_LED_2,
  5314. + .active_low = 1,
  5315. + }, {
  5316. + .name = "ja76pf:green:led3",
  5317. + .gpio = JA76PF_GPIO_LED_3,
  5318. + .active_low = 1,
  5319. + }
  5320. +};
  5321. +
  5322. +static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = {
  5323. + {
  5324. + .desc = "reset",
  5325. + .type = EV_KEY,
  5326. + .code = KEY_RESTART,
  5327. + .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL,
  5328. + .gpio = JA76PF_GPIO_BTN_RESET,
  5329. + .active_low = 1,
  5330. + }
  5331. +};
  5332. +
  5333. +static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = {
  5334. + .sda_pin = JA76PF_GPIO_I2C_SDA,
  5335. + .scl_pin = JA76PF_GPIO_I2C_SCL,
  5336. +};
  5337. +
  5338. +static struct platform_device ja76pf_i2c_gpio_device = {
  5339. + .name = "i2c-gpio",
  5340. + .id = 0,
  5341. + .dev = {
  5342. + .platform_data = &ja76pf_i2c_gpio_data,
  5343. + }
  5344. +};
  5345. +
  5346. +#define JA76PF_WAN_PHYMASK (1 << 4)
  5347. +#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3))
  5348. +#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK)
  5349. +
  5350. +static void __init ja76pf_init(void)
  5351. +{
  5352. + ar71xx_add_device_m25p80(NULL);
  5353. +
  5354. + ar71xx_add_device_mdio(~JA76PF_MDIO_PHYMASK);
  5355. +
  5356. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5357. + ar71xx_eth0_data.phy_mask = JA76PF_LAN_PHYMASK;
  5358. +
  5359. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5360. + ar71xx_eth1_data.phy_mask = JA76PF_WAN_PHYMASK;
  5361. + ar71xx_eth1_data.speed = SPEED_1000;
  5362. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  5363. +
  5364. + ar71xx_add_device_eth(0);
  5365. + ar71xx_add_device_eth(1);
  5366. +
  5367. + platform_device_register(&ja76pf_i2c_gpio_device);
  5368. +
  5369. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio),
  5370. + ja76pf_leds_gpio);
  5371. +
  5372. + ar71xx_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL,
  5373. + ARRAY_SIZE(ja76pf_gpio_keys),
  5374. + ja76pf_gpio_keys);
  5375. +
  5376. + ar71xx_add_device_usb();
  5377. + pb42_pci_init();
  5378. +}
  5379. +
  5380. +MIPS_MACHINE(AR71XX_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init);
  5381. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c
  5382. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c 1970-01-01 01:00:00.000000000 +0100
  5383. +++ linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c 2011-08-24 18:17:23.000000000 +0200
  5384. @@ -0,0 +1,83 @@
  5385. +/*
  5386. + * jjPlus JWAP003 board support
  5387. + *
  5388. + */
  5389. +
  5390. +#include <asm/mach-ar71xx/ar71xx.h>
  5391. +#include <linux/i2c.h>
  5392. +#include <linux/i2c-gpio.h>
  5393. +#include <linux/platform_device.h>
  5394. +
  5395. +#include "machtype.h"
  5396. +#include "devices.h"
  5397. +#include "dev-m25p80.h"
  5398. +#include "dev-gpio-buttons.h"
  5399. +#include "dev-pb42-pci.h"
  5400. +#include "dev-usb.h"
  5401. +
  5402. +#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */
  5403. +#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL)
  5404. +
  5405. +#define JWAP003_GPIO_WPS 11
  5406. +#define JWAP003_GPIO_I2C_SCL 0
  5407. +#define JWAP003_GPIO_I2C_SDA 1
  5408. +
  5409. +static struct gpio_keys_button jwap003_gpio_keys[] __initdata = {
  5410. + {
  5411. + .desc = "wps",
  5412. + .type = EV_KEY,
  5413. + .code = KEY_WPS_BUTTON,
  5414. + .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL,
  5415. + .gpio = JWAP003_GPIO_WPS,
  5416. + .active_low = 1,
  5417. + }
  5418. +};
  5419. +
  5420. +static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = {
  5421. + .sda_pin = JWAP003_GPIO_I2C_SDA,
  5422. + .scl_pin = JWAP003_GPIO_I2C_SCL,
  5423. +};
  5424. +
  5425. +static struct platform_device jwap003_i2c_gpio_device = {
  5426. + .name = "i2c-gpio",
  5427. + .id = 0,
  5428. + .dev = {
  5429. + .platform_data = &jwap003_i2c_gpio_data,
  5430. + }
  5431. +};
  5432. +
  5433. +#define JWAP003_WAN_PHYMASK BIT(0)
  5434. +#define JWAP003_LAN_PHYMASK BIT(4)
  5435. +
  5436. +static void __init jwap003_init(void)
  5437. +{
  5438. + ar71xx_add_device_m25p80(NULL);
  5439. +
  5440. + ar71xx_add_device_mdio(0x0);
  5441. +
  5442. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5443. + ar71xx_eth0_data.phy_mask = JWAP003_WAN_PHYMASK;
  5444. + ar71xx_eth0_data.speed = SPEED_100;
  5445. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5446. + ar71xx_eth0_data.has_ar8216 = 1;
  5447. +
  5448. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5449. + ar71xx_eth1_data.phy_mask = JWAP003_LAN_PHYMASK;
  5450. + ar71xx_eth1_data.speed = SPEED_100;
  5451. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  5452. +
  5453. + ar71xx_add_device_eth(0);
  5454. + ar71xx_add_device_eth(1);
  5455. +
  5456. + platform_device_register(&jwap003_i2c_gpio_device);
  5457. +
  5458. + ar71xx_add_device_usb();
  5459. +
  5460. + ar71xx_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL,
  5461. + ARRAY_SIZE(jwap003_gpio_keys),
  5462. + jwap003_gpio_keys);
  5463. +
  5464. + pb42_pci_init();
  5465. +}
  5466. +
  5467. +MIPS_MACHINE(AR71XX_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init);
  5468. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c
  5469. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100
  5470. +++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-08-24 18:17:23.000000000 +0200
  5471. @@ -0,0 +1,166 @@
  5472. +/*
  5473. + * Planex MZK-W04NU board support
  5474. + *
  5475. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5476. + *
  5477. + * This program is free software; you can redistribute it and/or modify it
  5478. + * under the terms of the GNU General Public License version 2 as published
  5479. + * by the Free Software Foundation.
  5480. + */
  5481. +
  5482. +#include <linux/mtd/mtd.h>
  5483. +#include <linux/mtd/partitions.h>
  5484. +
  5485. +#include <asm/mach-ar71xx/ar71xx.h>
  5486. +
  5487. +#include "machtype.h"
  5488. +#include "devices.h"
  5489. +#include "dev-ar9xxx-wmac.h"
  5490. +#include "dev-gpio-buttons.h"
  5491. +#include "dev-leds-gpio.h"
  5492. +#include "dev-m25p80.h"
  5493. +#include "dev-usb.h"
  5494. +
  5495. +#define MZK_W04NU_GPIO_LED_USB 0
  5496. +#define MZK_W04NU_GPIO_LED_STATUS 1
  5497. +#define MZK_W04NU_GPIO_LED_WPS 3
  5498. +#define MZK_W04NU_GPIO_LED_WLAN 6
  5499. +#define MZK_W04NU_GPIO_LED_AP 15
  5500. +#define MZK_W04NU_GPIO_LED_ROUTER 16
  5501. +
  5502. +#define MZK_W04NU_GPIO_BTN_APROUTER 5
  5503. +#define MZK_W04NU_GPIO_BTN_WPS 12
  5504. +#define MZK_W04NU_GPIO_BTN_RESET 21
  5505. +
  5506. +#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */
  5507. +#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL)
  5508. +
  5509. +#ifdef CONFIG_MTD_PARTITIONS
  5510. +static struct mtd_partition mzk_w04nu_partitions[] = {
  5511. + {
  5512. + .name = "u-boot",
  5513. + .offset = 0,
  5514. + .size = 0x040000,
  5515. + .mask_flags = MTD_WRITEABLE,
  5516. + }, {
  5517. + .name = "u-boot-env",
  5518. + .offset = 0x040000,
  5519. + .size = 0x010000,
  5520. + }, {
  5521. + .name = "kernel",
  5522. + .offset = 0x050000,
  5523. + .size = 0x160000,
  5524. + }, {
  5525. + .name = "rootfs",
  5526. + .offset = 0x1b0000,
  5527. + .size = 0x630000,
  5528. + }, {
  5529. + .name = "art",
  5530. + .offset = 0x7e0000,
  5531. + .size = 0x020000,
  5532. + .mask_flags = MTD_WRITEABLE,
  5533. + }, {
  5534. + .name = "firmware",
  5535. + .offset = 0x050000,
  5536. + .size = 0x790000,
  5537. + }
  5538. +};
  5539. +#endif /* CONFIG_MTD_PARTITIONS */
  5540. +
  5541. +static struct flash_platform_data mzk_w04nu_flash_data = {
  5542. +#ifdef CONFIG_MTD_PARTITIONS
  5543. + .parts = mzk_w04nu_partitions,
  5544. + .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions),
  5545. +#endif
  5546. +};
  5547. +
  5548. +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
  5549. + {
  5550. + .name = "mzk-w04nu:green:status",
  5551. + .gpio = MZK_W04NU_GPIO_LED_STATUS,
  5552. + .active_low = 1,
  5553. + }, {
  5554. + .name = "mzk-w04nu:blue:wps",
  5555. + .gpio = MZK_W04NU_GPIO_LED_WPS,
  5556. + .active_low = 1,
  5557. + }, {
  5558. + .name = "mzk-w04nu:green:wlan",
  5559. + .gpio = MZK_W04NU_GPIO_LED_WLAN,
  5560. + .active_low = 1,
  5561. + }, {
  5562. + .name = "mzk-w04nu:green:usb",
  5563. + .gpio = MZK_W04NU_GPIO_LED_USB,
  5564. + .active_low = 1,
  5565. + }, {
  5566. + .name = "mzk-w04nu:green:ap",
  5567. + .gpio = MZK_W04NU_GPIO_LED_AP,
  5568. + .active_low = 1,
  5569. + }, {
  5570. + .name = "mzk-w04nu:green:router",
  5571. + .gpio = MZK_W04NU_GPIO_LED_ROUTER,
  5572. + .active_low = 1,
  5573. + }
  5574. +};
  5575. +
  5576. +static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = {
  5577. + {
  5578. + .desc = "reset",
  5579. + .type = EV_KEY,
  5580. + .code = KEY_RESTART,
  5581. + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL,
  5582. + .gpio = MZK_W04NU_GPIO_BTN_RESET,
  5583. + .active_low = 1,
  5584. + }, {
  5585. + .desc = "wps",
  5586. + .type = EV_KEY,
  5587. + .code = KEY_WPS_BUTTON,
  5588. + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL,
  5589. + .gpio = MZK_W04NU_GPIO_BTN_WPS,
  5590. + .active_low = 1,
  5591. + }, {
  5592. + .desc = "aprouter",
  5593. + .type = EV_KEY,
  5594. + .code = BTN_2,
  5595. + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL,
  5596. + .gpio = MZK_W04NU_GPIO_BTN_APROUTER,
  5597. + .active_low = 0,
  5598. + }
  5599. +};
  5600. +
  5601. +#define MZK_W04NU_WAN_PHYMASK BIT(4)
  5602. +#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK)
  5603. +
  5604. +static void __init mzk_w04nu_setup(void)
  5605. +{
  5606. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5607. +
  5608. + ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK);
  5609. +
  5610. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0);
  5611. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5612. + ar71xx_eth0_data.speed = SPEED_100;
  5613. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5614. + ar71xx_eth0_data.has_ar8216 = 1;
  5615. +
  5616. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1);
  5617. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5618. + ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK;
  5619. +
  5620. + ar71xx_add_device_eth(0);
  5621. + ar71xx_add_device_eth(1);
  5622. +
  5623. + ar71xx_add_device_m25p80(&mzk_w04nu_flash_data);
  5624. +
  5625. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
  5626. + mzk_w04nu_leds_gpio);
  5627. +
  5628. + ar71xx_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL,
  5629. + ARRAY_SIZE(mzk_w04nu_gpio_keys),
  5630. + mzk_w04nu_gpio_keys);
  5631. + ar71xx_add_device_usb();
  5632. +
  5633. + ar9xxx_add_device_wmac(eeprom, NULL);
  5634. +}
  5635. +
  5636. +MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU",
  5637. + mzk_w04nu_setup);
  5638. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c
  5639. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100
  5640. +++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-08-24 18:17:23.000000000 +0200
  5641. @@ -0,0 +1,159 @@
  5642. +/*
  5643. + * Planex MZK-W300NH board support
  5644. + *
  5645. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  5646. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5647. + *
  5648. + * This program is free software; you can redistribute it and/or modify it
  5649. + * under the terms of the GNU General Public License version 2 as published
  5650. + * by the Free Software Foundation.
  5651. + */
  5652. +
  5653. +#include <linux/mtd/mtd.h>
  5654. +#include <linux/mtd/partitions.h>
  5655. +
  5656. +#include <asm/mach-ar71xx/ar71xx.h>
  5657. +
  5658. +#include "machtype.h"
  5659. +#include "devices.h"
  5660. +#include "dev-m25p80.h"
  5661. +#include "dev-ar9xxx-wmac.h"
  5662. +#include "dev-gpio-buttons.h"
  5663. +#include "dev-leds-gpio.h"
  5664. +
  5665. +#define MZK_W300NH_GPIO_LED_STATUS 1
  5666. +#define MZK_W300NH_GPIO_LED_WPS 3
  5667. +#define MZK_W300NH_GPIO_LED_WLAN 6
  5668. +#define MZK_W300NH_GPIO_LED_AP 15
  5669. +#define MZK_W300NH_GPIO_LED_ROUTER 16
  5670. +
  5671. +#define MZK_W300NH_GPIO_BTN_APROUTER 5
  5672. +#define MZK_W300NH_GPIO_BTN_WPS 12
  5673. +#define MZK_W300NH_GPIO_BTN_RESET 21
  5674. +
  5675. +#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */
  5676. +#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL)
  5677. +
  5678. +#ifdef CONFIG_MTD_PARTITIONS
  5679. +static struct mtd_partition mzk_w300nh_partitions[] = {
  5680. + {
  5681. + .name = "u-boot",
  5682. + .offset = 0,
  5683. + .size = 0x040000,
  5684. + .mask_flags = MTD_WRITEABLE,
  5685. + }, {
  5686. + .name = "u-boot-env",
  5687. + .offset = 0x040000,
  5688. + .size = 0x010000,
  5689. + }, {
  5690. + .name = "kernel",
  5691. + .offset = 0x050000,
  5692. + .size = 0x160000,
  5693. + }, {
  5694. + .name = "rootfs",
  5695. + .offset = 0x1b0000,
  5696. + .size = 0x630000,
  5697. + }, {
  5698. + .name = "art",
  5699. + .offset = 0x7e0000,
  5700. + .size = 0x020000,
  5701. + .mask_flags = MTD_WRITEABLE,
  5702. + }, {
  5703. + .name = "firmware",
  5704. + .offset = 0x050000,
  5705. + .size = 0x790000,
  5706. + }
  5707. +};
  5708. +#endif /* CONFIG_MTD_PARTITIONS */
  5709. +
  5710. +static struct flash_platform_data mzk_w300nh_flash_data = {
  5711. +#ifdef CONFIG_MTD_PARTITIONS
  5712. + .parts = mzk_w300nh_partitions,
  5713. + .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions),
  5714. +#endif
  5715. +};
  5716. +
  5717. +static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = {
  5718. + {
  5719. + .name = "mzk-w300nh:green:status",
  5720. + .gpio = MZK_W300NH_GPIO_LED_STATUS,
  5721. + .active_low = 1,
  5722. + }, {
  5723. + .name = "mzk-w300nh:blue:wps",
  5724. + .gpio = MZK_W300NH_GPIO_LED_WPS,
  5725. + .active_low = 1,
  5726. + }, {
  5727. + .name = "mzk-w300nh:green:wlan",
  5728. + .gpio = MZK_W300NH_GPIO_LED_WLAN,
  5729. + .active_low = 1,
  5730. + }, {
  5731. + .name = "mzk-w300nh:green:ap",
  5732. + .gpio = MZK_W300NH_GPIO_LED_AP,
  5733. + .active_low = 1,
  5734. + }, {
  5735. + .name = "mzk-w300nh:green:router",
  5736. + .gpio = MZK_W300NH_GPIO_LED_ROUTER,
  5737. + .active_low = 1,
  5738. + }
  5739. +};
  5740. +
  5741. +static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = {
  5742. + {
  5743. + .desc = "reset",
  5744. + .type = EV_KEY,
  5745. + .code = KEY_RESTART,
  5746. + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL,
  5747. + .gpio = MZK_W300NH_GPIO_BTN_RESET,
  5748. + .active_low = 1,
  5749. + }, {
  5750. + .desc = "wps",
  5751. + .type = EV_KEY,
  5752. + .code = KEY_WPS_BUTTON,
  5753. + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL,
  5754. + .gpio = MZK_W300NH_GPIO_BTN_WPS,
  5755. + .active_low = 1,
  5756. + }, {
  5757. + .desc = "aprouter",
  5758. + .type = EV_KEY,
  5759. + .code = BTN_2,
  5760. + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL,
  5761. + .gpio = MZK_W300NH_GPIO_BTN_APROUTER,
  5762. + .active_low = 0,
  5763. + }
  5764. +};
  5765. +
  5766. +#define MZK_W300NH_WAN_PHYMASK BIT(4)
  5767. +#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK)
  5768. +
  5769. +static void __init mzk_w300nh_setup(void)
  5770. +{
  5771. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5772. +
  5773. + ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK);
  5774. +
  5775. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0);
  5776. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5777. + ar71xx_eth0_data.speed = SPEED_100;
  5778. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5779. + ar71xx_eth0_data.has_ar8216 = 1;
  5780. +
  5781. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1);
  5782. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5783. + ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK;
  5784. +
  5785. + ar71xx_add_device_eth(0);
  5786. + ar71xx_add_device_eth(1);
  5787. +
  5788. + ar71xx_add_device_m25p80(&mzk_w300nh_flash_data);
  5789. +
  5790. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio),
  5791. + mzk_w300nh_leds_gpio);
  5792. +
  5793. + ar71xx_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL,
  5794. + ARRAY_SIZE(mzk_w300nh_gpio_keys),
  5795. + mzk_w300nh_gpio_keys);
  5796. + ar9xxx_add_device_wmac(eeprom, NULL);
  5797. +}
  5798. +
  5799. +MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH",
  5800. + mzk_w300nh_setup);
  5801. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c
  5802. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100
  5803. +++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-08-24 18:17:23.000000000 +0200
  5804. @@ -0,0 +1,225 @@
  5805. +/*
  5806. + * Zyxel NBG 460N/550N/550NH board support
  5807. + *
  5808. + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
  5809. + *
  5810. + * based on mach-tl-wr1043nd.c
  5811. + *
  5812. + * This program is free software; you can redistribute it and/or modify it
  5813. + * under the terms of the GNU General Public License version 2 as published
  5814. + * by the Free Software Foundation.
  5815. + */
  5816. +
  5817. +#include <linux/platform_device.h>
  5818. +#include <linux/mtd/mtd.h>
  5819. +#include <linux/mtd/partitions.h>
  5820. +#include <linux/delay.h>
  5821. +#include <linux/rtl8366.h>
  5822. +
  5823. +#include <linux/i2c.h>
  5824. +#include <linux/i2c-algo-bit.h>
  5825. +#include <linux/i2c-gpio.h>
  5826. +
  5827. +#include <asm/mach-ar71xx/ar71xx.h>
  5828. +
  5829. +#include "machtype.h"
  5830. +#include "devices.h"
  5831. +#include "dev-m25p80.h"
  5832. +#include "dev-ar9xxx-wmac.h"
  5833. +#include "dev-gpio-buttons.h"
  5834. +#include "dev-leds-gpio.h"
  5835. +
  5836. +/* LEDs */
  5837. +#define NBG460N_GPIO_LED_WPS 3
  5838. +#define NBG460N_GPIO_LED_WAN 6
  5839. +#define NBG460N_GPIO_LED_POWER 14
  5840. +#define NBG460N_GPIO_LED_WLAN 15
  5841. +
  5842. +/* Buttons */
  5843. +#define NBG460N_GPIO_BTN_WPS 12
  5844. +#define NBG460N_GPIO_BTN_RESET 21
  5845. +
  5846. +#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */
  5847. +#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL)
  5848. +
  5849. +/* RTC chip PCF8563 I2C interface */
  5850. +#define NBG460N_GPIO_PCF8563_SDA 8
  5851. +#define NBG460N_GPIO_PCF8563_SCK 7
  5852. +
  5853. +/* Switch configuration I2C interface */
  5854. +#define NBG460N_GPIO_RTL8366_SDA 16
  5855. +#define NBG460N_GPIO_RTL8366_SCK 18
  5856. +
  5857. +#ifdef CONFIG_MTD_PARTITIONS
  5858. +static struct mtd_partition nbg460n_partitions[] = {
  5859. + {
  5860. + .name = "Bootbase",
  5861. + .offset = 0,
  5862. + .size = 0x010000,
  5863. + .mask_flags = MTD_WRITEABLE,
  5864. + }, {
  5865. + .name = "U-Boot Config",
  5866. + .offset = 0x010000,
  5867. + .size = 0x030000,
  5868. + }, {
  5869. + .name = "U-Boot",
  5870. + .offset = 0x040000,
  5871. + .size = 0x030000,
  5872. + }, {
  5873. + .name = "linux",
  5874. + .offset = 0x070000,
  5875. + .size = 0x0e0000,
  5876. + }, {
  5877. + .name = "rootfs",
  5878. + .offset = 0x150000,
  5879. + .size = 0x2a0000,
  5880. + }, {
  5881. + .name = "CalibData",
  5882. + .offset = 0x3f0000,
  5883. + .size = 0x010000,
  5884. + .mask_flags = MTD_WRITEABLE,
  5885. + }, {
  5886. + .name = "firmware",
  5887. + .offset = 0x070000,
  5888. + .size = 0x380000,
  5889. + }
  5890. +};
  5891. +#endif /* CONFIG_MTD_PARTITIONS */
  5892. +
  5893. +static struct flash_platform_data nbg460n_flash_data = {
  5894. +#ifdef CONFIG_MTD_PARTITIONS
  5895. + .parts = nbg460n_partitions,
  5896. + .nr_parts = ARRAY_SIZE(nbg460n_partitions),
  5897. +#endif
  5898. +};
  5899. +
  5900. +static struct gpio_led nbg460n_leds_gpio[] __initdata = {
  5901. + {
  5902. + .name = "nbg460n:green:power",
  5903. + .gpio = NBG460N_GPIO_LED_POWER,
  5904. + .active_low = 0,
  5905. + .default_trigger = "default-on",
  5906. + }, {
  5907. + .name = "nbg460n:green:wps",
  5908. + .gpio = NBG460N_GPIO_LED_WPS,
  5909. + .active_low = 0,
  5910. + }, {
  5911. + .name = "nbg460n:green:wlan",
  5912. + .gpio = NBG460N_GPIO_LED_WLAN,
  5913. + .active_low = 0,
  5914. + }, {
  5915. + /* Not really for controlling the LED,
  5916. + when set low the LED blinks uncontrollable */
  5917. + .name = "nbg460n:green:wan",
  5918. + .gpio = NBG460N_GPIO_LED_WAN,
  5919. + .active_low = 0,
  5920. + }
  5921. +};
  5922. +
  5923. +static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = {
  5924. + {
  5925. + .desc = "reset",
  5926. + .type = EV_KEY,
  5927. + .code = KEY_RESTART,
  5928. + .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL,
  5929. + .gpio = NBG460N_GPIO_BTN_RESET,
  5930. + .active_low = 1,
  5931. + }, {
  5932. + .desc = "wps",
  5933. + .type = EV_KEY,
  5934. + .code = KEY_WPS_BUTTON,
  5935. + .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL,
  5936. + .gpio = NBG460N_GPIO_BTN_WPS,
  5937. + .active_low = 1,
  5938. + }
  5939. +};
  5940. +
  5941. +static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = {
  5942. + .sda_pin = NBG460N_GPIO_PCF8563_SDA,
  5943. + .scl_pin = NBG460N_GPIO_PCF8563_SCK,
  5944. + .udelay = 10,
  5945. +};
  5946. +
  5947. +static struct platform_device nbg460n_i2c_device = {
  5948. + .name = "i2c-gpio",
  5949. + .id = -1,
  5950. + .num_resources = 0,
  5951. + .resource = NULL,
  5952. + .dev = {
  5953. + .platform_data = &nbg460n_i2c_device_platdata,
  5954. + },
  5955. +};
  5956. +
  5957. +static struct i2c_board_info nbg460n_i2c_devs[] __initdata = {
  5958. + {
  5959. + I2C_BOARD_INFO("pcf8563", 0x51),
  5960. + },
  5961. +};
  5962. +
  5963. +static void __devinit nbg460n_i2c_init(void)
  5964. +{
  5965. + /* The gpio interface */
  5966. + platform_device_register(&nbg460n_i2c_device);
  5967. + /* I2C devices */
  5968. + i2c_register_board_info(0, nbg460n_i2c_devs,
  5969. + ARRAY_SIZE(nbg460n_i2c_devs));
  5970. +}
  5971. +
  5972. +
  5973. +static struct rtl8366_platform_data nbg460n_rtl8366s_data = {
  5974. + .gpio_sda = NBG460N_GPIO_RTL8366_SDA,
  5975. + .gpio_sck = NBG460N_GPIO_RTL8366_SCK,
  5976. +};
  5977. +
  5978. +static struct platform_device nbg460n_rtl8366s_device = {
  5979. + .name = RTL8366S_DRIVER_NAME,
  5980. + .id = -1,
  5981. + .dev = {
  5982. + .platform_data = &nbg460n_rtl8366s_data,
  5983. + }
  5984. +};
  5985. +
  5986. +static void __init nbg460n_setup(void)
  5987. +{
  5988. + /* end of bootloader sector contains mac address */
  5989. + u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8);
  5990. + /* last sector contains wlan calib data */
  5991. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5992. +
  5993. + /* LAN Port */
  5994. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  5995. + ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  5996. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5997. + ar71xx_eth0_data.speed = SPEED_1000;
  5998. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5999. +
  6000. + /* WAN Port */
  6001. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  6002. + ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  6003. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6004. + ar71xx_eth1_data.phy_mask = 0x10;
  6005. +
  6006. + ar71xx_add_device_eth(0);
  6007. + ar71xx_add_device_eth(1);
  6008. +
  6009. + /* register the switch phy */
  6010. + platform_device_register(&nbg460n_rtl8366s_device);
  6011. +
  6012. + /* register flash */
  6013. + ar71xx_add_device_m25p80(&nbg460n_flash_data);
  6014. +
  6015. + ar9xxx_add_device_wmac(eeprom, mac);
  6016. +
  6017. + /* register RTC chip */
  6018. + nbg460n_i2c_init();
  6019. +
  6020. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio),
  6021. + nbg460n_leds_gpio);
  6022. +
  6023. + ar71xx_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL,
  6024. + ARRAY_SIZE(nbg460n_gpio_keys),
  6025. + nbg460n_gpio_keys);
  6026. +}
  6027. +
  6028. +MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH",
  6029. + nbg460n_setup);
  6030. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c
  6031. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100
  6032. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-08-24 18:17:23.000000000 +0200
  6033. @@ -0,0 +1,74 @@
  6034. +/*
  6035. + * Atheros PB42 board support
  6036. + *
  6037. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6038. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6039. + *
  6040. + * This program is free software; you can redistribute it and/or modify it
  6041. + * under the terms of the GNU General Public License version 2 as published
  6042. + * by the Free Software Foundation.
  6043. + */
  6044. +
  6045. +#include <asm/mach-ar71xx/ar71xx.h>
  6046. +
  6047. +#include "machtype.h"
  6048. +#include "devices.h"
  6049. +#include "dev-m25p80.h"
  6050. +#include "dev-gpio-buttons.h"
  6051. +#include "dev-pb42-pci.h"
  6052. +#include "dev-usb.h"
  6053. +
  6054. +#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */
  6055. +#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL)
  6056. +
  6057. +#define PB42_GPIO_BTN_SW4 8
  6058. +#define PB42_GPIO_BTN_SW5 3
  6059. +
  6060. +static struct gpio_keys_button pb42_gpio_keys[] __initdata = {
  6061. + {
  6062. + .desc = "sw4",
  6063. + .type = EV_KEY,
  6064. + .code = BTN_0,
  6065. + .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL,
  6066. + .gpio = PB42_GPIO_BTN_SW4,
  6067. + .active_low = 1,
  6068. + }, {
  6069. + .desc = "sw5",
  6070. + .type = EV_KEY,
  6071. + .code = BTN_1,
  6072. + .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL,
  6073. + .gpio = PB42_GPIO_BTN_SW5,
  6074. + .active_low = 1,
  6075. + }
  6076. +};
  6077. +
  6078. +#define PB42_WAN_PHYMASK BIT(20)
  6079. +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  6080. +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
  6081. +
  6082. +static void __init pb42_init(void)
  6083. +{
  6084. + ar71xx_add_device_m25p80(NULL);
  6085. +
  6086. + ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
  6087. +
  6088. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  6089. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6090. + ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
  6091. +
  6092. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1);
  6093. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6094. + ar71xx_eth1_data.speed = SPEED_100;
  6095. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6096. +
  6097. + ar71xx_add_device_eth(0);
  6098. + ar71xx_add_device_eth(1);
  6099. +
  6100. + ar71xx_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL,
  6101. + ARRAY_SIZE(pb42_gpio_keys),
  6102. + pb42_gpio_keys);
  6103. +
  6104. + pb42_pci_init();
  6105. +}
  6106. +
  6107. +MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init);
  6108. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c
  6109. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100
  6110. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-08-24 18:17:23.000000000 +0200
  6111. @@ -0,0 +1,213 @@
  6112. +/*
  6113. + * Atheros PB44 board support
  6114. + *
  6115. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  6116. + *
  6117. + * This program is free software; you can redistribute it and/or modify it
  6118. + * under the terms of the GNU General Public License version 2 as published
  6119. + * by the Free Software Foundation.
  6120. + */
  6121. +
  6122. +#include <linux/init.h>
  6123. +#include <linux/bitops.h>
  6124. +#include <linux/delay.h>
  6125. +#include <linux/platform_device.h>
  6126. +#include <linux/spi/spi.h>
  6127. +#include <linux/spi/flash.h>
  6128. +#include <linux/spi/vsc7385.h>
  6129. +#include <linux/i2c.h>
  6130. +#include <linux/i2c-gpio.h>
  6131. +#include <linux/i2c/pcf857x.h>
  6132. +
  6133. +#include <asm/mach-ar71xx/ar71xx.h>
  6134. +
  6135. +#include "machtype.h"
  6136. +#include "devices.h"
  6137. +#include "dev-pb42-pci.h"
  6138. +#include "dev-gpio-buttons.h"
  6139. +#include "dev-leds-gpio.h"
  6140. +#include "dev-usb.h"
  6141. +
  6142. +#define PB44_PCF8757_VSC7395_CS 0
  6143. +#define PB44_PCF8757_STEREO_CS 1
  6144. +#define PB44_PCF8757_SLIC_CS0 2
  6145. +#define PB44_PCF8757_SLIC_TEST 3
  6146. +#define PB44_PCF8757_SLIC_INT0 4
  6147. +#define PB44_PCF8757_SLIC_INT1 5
  6148. +#define PB44_PCF8757_SW_RESET 6
  6149. +#define PB44_PCF8757_SW_JUMP 8
  6150. +#define PB44_PCF8757_LED_JUMP1 9
  6151. +#define PB44_PCF8757_LED_JUMP2 10
  6152. +#define PB44_PCF8757_TP24 11
  6153. +#define PB44_PCF8757_TP25 12
  6154. +#define PB44_PCF8757_TP26 13
  6155. +#define PB44_PCF8757_TP27 14
  6156. +#define PB44_PCF8757_TP28 15
  6157. +
  6158. +#define PB44_GPIO_I2C_SCL 0
  6159. +#define PB44_GPIO_I2C_SDA 1
  6160. +
  6161. +#define PB44_GPIO_EXP_BASE 16
  6162. +#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS)
  6163. +#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET)
  6164. +#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP)
  6165. +#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1)
  6166. +#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2)
  6167. +
  6168. +#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
  6169. +#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
  6170. +
  6171. +static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
  6172. + .sda_pin = PB44_GPIO_I2C_SDA,
  6173. + .scl_pin = PB44_GPIO_I2C_SCL,
  6174. +};
  6175. +
  6176. +static struct platform_device pb44_i2c_gpio_device = {
  6177. + .name = "i2c-gpio",
  6178. + .id = 0,
  6179. + .dev = {
  6180. + .platform_data = &pb44_i2c_gpio_data,
  6181. + }
  6182. +};
  6183. +
  6184. +static struct pcf857x_platform_data pb44_pcf857x_data = {
  6185. + .gpio_base = PB44_GPIO_EXP_BASE,
  6186. +};
  6187. +
  6188. +static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
  6189. + {
  6190. + I2C_BOARD_INFO("pcf8575", 0x20),
  6191. + .platform_data = &pb44_pcf857x_data,
  6192. + },
  6193. +};
  6194. +
  6195. +static struct gpio_led pb44_leds_gpio[] __initdata = {
  6196. + {
  6197. + .name = "pb44:amber:jump1",
  6198. + .gpio = PB44_GPIO_LED_JUMP1,
  6199. + .active_low = 1,
  6200. + }, {
  6201. + .name = "pb44:green:jump2",
  6202. + .gpio = PB44_GPIO_LED_JUMP2,
  6203. + .active_low = 1,
  6204. + },
  6205. +};
  6206. +
  6207. +static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
  6208. + {
  6209. + .desc = "soft_reset",
  6210. + .type = EV_KEY,
  6211. + .code = KEY_RESTART,
  6212. + .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
  6213. + .gpio = PB44_GPIO_SW_RESET,
  6214. + .active_low = 1,
  6215. + }, {
  6216. + .desc = "jumpstart",
  6217. + .type = EV_KEY,
  6218. + .code = KEY_WPS_BUTTON,
  6219. + .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
  6220. + .gpio = PB44_GPIO_SW_JUMP,
  6221. + .active_low = 1,
  6222. + }
  6223. +};
  6224. +
  6225. +static void pb44_vsc7395_reset(void)
  6226. +{
  6227. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  6228. + udelay(10);
  6229. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  6230. + mdelay(50);
  6231. +}
  6232. +
  6233. +static struct vsc7385_platform_data pb44_vsc7395_data = {
  6234. + .reset = pb44_vsc7395_reset,
  6235. + .ucode_name = "vsc7395_ucode_pb44.bin",
  6236. + .mac_cfg = {
  6237. + .tx_ipg = 6,
  6238. + .bit2 = 1,
  6239. + .clk_sel = 0,
  6240. + },
  6241. +};
  6242. +
  6243. +static struct spi_board_info pb44_spi_info[] = {
  6244. + {
  6245. + .bus_num = 0,
  6246. + .chip_select = 0,
  6247. + .max_speed_hz = 25000000,
  6248. + .modalias = "m25p80",
  6249. + }, {
  6250. + .bus_num = 0,
  6251. + .chip_select = 1,
  6252. + .max_speed_hz = 25000000,
  6253. + .modalias = "spi-vsc7385",
  6254. + .platform_data = &pb44_vsc7395_data,
  6255. + .controller_data = (void *) PB44_GPIO_VSC7395_CS,
  6256. + },
  6257. +};
  6258. +
  6259. +static struct resource pb44_spi_resources[] = {
  6260. + [0] = {
  6261. + .start = AR71XX_SPI_BASE,
  6262. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  6263. + .flags = IORESOURCE_MEM,
  6264. + },
  6265. +};
  6266. +
  6267. +static struct ar71xx_spi_platform_data pb44_spi_data = {
  6268. + .bus_num = 0,
  6269. + .num_chipselect = 2,
  6270. +};
  6271. +
  6272. +static struct platform_device pb44_spi_device = {
  6273. + .name = "pb44-spi",
  6274. + .id = -1,
  6275. + .resource = pb44_spi_resources,
  6276. + .num_resources = ARRAY_SIZE(pb44_spi_resources),
  6277. + .dev = {
  6278. + .platform_data = &pb44_spi_data,
  6279. + },
  6280. +};
  6281. +
  6282. +#define PB44_WAN_PHYMASK BIT(0)
  6283. +#define PB44_LAN_PHYMASK 0
  6284. +#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK)
  6285. +
  6286. +static void __init pb44_init(void)
  6287. +{
  6288. + ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK);
  6289. +
  6290. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  6291. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6292. + ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK;
  6293. +
  6294. + ar71xx_add_device_eth(0);
  6295. +
  6296. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1);
  6297. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6298. + ar71xx_eth1_data.speed = SPEED_1000;
  6299. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6300. + ar71xx_eth1_pll_data.pll_1000 = 0x110000;
  6301. +
  6302. + ar71xx_add_device_eth(1);
  6303. +
  6304. + ar71xx_add_device_usb();
  6305. +
  6306. + pb42_pci_init();
  6307. +
  6308. + i2c_register_board_info(0, pb44_i2c_board_info,
  6309. + ARRAY_SIZE(pb44_i2c_board_info));
  6310. +
  6311. + platform_device_register(&pb44_i2c_gpio_device);
  6312. +
  6313. + spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info));
  6314. + platform_device_register(&pb44_spi_device);
  6315. +
  6316. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
  6317. + pb44_leds_gpio);
  6318. +
  6319. + ar71xx_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
  6320. + ARRAY_SIZE(pb44_gpio_keys),
  6321. + pb44_gpio_keys);
  6322. +}
  6323. +
  6324. +MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init);
  6325. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c
  6326. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100
  6327. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-08-24 18:17:23.000000000 +0200
  6328. @@ -0,0 +1,105 @@
  6329. +/*
  6330. + * Atheros PB92 board support
  6331. + *
  6332. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  6333. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6334. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6335. + *
  6336. + * This program is free software; you can redistribute it and/or modify it
  6337. + * under the terms of the GNU General Public License version 2 as published
  6338. + * by the Free Software Foundation.
  6339. + */
  6340. +
  6341. +#include <linux/mtd/mtd.h>
  6342. +#include <linux/mtd/partitions.h>
  6343. +#include <asm/mach-ar71xx/ar71xx.h>
  6344. +
  6345. +#include "machtype.h"
  6346. +#include "devices.h"
  6347. +#include "dev-m25p80.h"
  6348. +#include "dev-gpio-buttons.h"
  6349. +#include "dev-pb9x-pci.h"
  6350. +#include "dev-usb.h"
  6351. +
  6352. +#ifdef CONFIG_MTD_PARTITIONS
  6353. +static struct mtd_partition pb92_partitions[] = {
  6354. + {
  6355. + .name = "u-boot",
  6356. + .offset = 0,
  6357. + .size = 0x040000,
  6358. + .mask_flags = MTD_WRITEABLE,
  6359. + }, {
  6360. + .name = "u-boot-env",
  6361. + .offset = 0x040000,
  6362. + .size = 0x010000,
  6363. + }, {
  6364. + .name = "rootfs",
  6365. + .offset = 0x050000,
  6366. + .size = 0x2b0000,
  6367. + }, {
  6368. + .name = "uImage",
  6369. + .offset = 0x300000,
  6370. + .size = 0x0e0000,
  6371. + }, {
  6372. + .name = "ART",
  6373. + .offset = 0x3e0000,
  6374. + .size = 0x020000,
  6375. + .mask_flags = MTD_WRITEABLE,
  6376. + }
  6377. +};
  6378. +#endif /* CONFIG_MTD_PARTITIONS */
  6379. +
  6380. +static struct flash_platform_data pb92_flash_data = {
  6381. +#ifdef CONFIG_MTD_PARTITIONS
  6382. + .parts = pb92_partitions,
  6383. + .nr_parts = ARRAY_SIZE(pb92_partitions),
  6384. +#endif
  6385. +};
  6386. +
  6387. +#define PB92_KEYS_POLL_INTERVAL 20 /* msecs */
  6388. +#define PB92_KEYS_DEBOUNCE_INTERVAL (3 * PB92_KEYS_POLL_INTERVAL)
  6389. +
  6390. +#define PB92_GPIO_BTN_SW4 8
  6391. +#define PB92_GPIO_BTN_SW5 3
  6392. +
  6393. +static struct gpio_keys_button pb92_gpio_keys[] __initdata = {
  6394. + {
  6395. + .desc = "sw4",
  6396. + .type = EV_KEY,
  6397. + .code = BTN_0,
  6398. + .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL,
  6399. + .gpio = PB92_GPIO_BTN_SW4,
  6400. + .active_low = 1,
  6401. + }, {
  6402. + .desc = "sw5",
  6403. + .type = EV_KEY,
  6404. + .code = BTN_1,
  6405. + .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL,
  6406. + .gpio = PB92_GPIO_BTN_SW5,
  6407. + .active_low = 1,
  6408. + }
  6409. +};
  6410. +
  6411. +static void __init pb92_init(void)
  6412. +{
  6413. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  6414. +
  6415. + ar71xx_add_device_m25p80(&pb92_flash_data);
  6416. +
  6417. + ar71xx_add_device_mdio(~BIT(0));
  6418. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  6419. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6420. + ar71xx_eth0_data.speed = SPEED_1000;
  6421. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6422. + ar71xx_eth0_data.phy_mask = BIT(0);
  6423. +
  6424. + ar71xx_add_device_eth(0);
  6425. +
  6426. + ar71xx_register_gpio_keys_polled(-1, PB92_KEYS_POLL_INTERVAL,
  6427. + ARRAY_SIZE(pb92_gpio_keys),
  6428. + pb92_gpio_keys);
  6429. +
  6430. + pb9x_pci_init();
  6431. +}
  6432. +
  6433. +MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init);
  6434. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c
  6435. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100
  6436. +++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-08-24 18:17:23.000000000 +0200
  6437. @@ -0,0 +1,344 @@
  6438. +/*
  6439. + * MikroTik RouterBOARD 4xx series support
  6440. + *
  6441. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  6442. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6443. + *
  6444. + * This program is free software; you can redistribute it and/or modify it
  6445. + * under the terms of the GNU General Public License version 2 as published
  6446. + * by the Free Software Foundation.
  6447. + */
  6448. +
  6449. +#include <linux/platform_device.h>
  6450. +#include <linux/irq.h>
  6451. +#include <linux/mmc/host.h>
  6452. +#include <linux/spi/spi.h>
  6453. +#include <linux/spi/flash.h>
  6454. +#include <linux/spi/mmc_spi.h>
  6455. +#include <linux/mtd/mtd.h>
  6456. +#include <linux/mtd/partitions.h>
  6457. +
  6458. +#include <asm/mach-ar71xx/ar71xx.h>
  6459. +#include <asm/mach-ar71xx/pci.h>
  6460. +#include <asm/mach-ar71xx/rb4xx_cpld.h>
  6461. +
  6462. +#include "machtype.h"
  6463. +#include "devices.h"
  6464. +#include "dev-gpio-buttons.h"
  6465. +#include "dev-leds-gpio.h"
  6466. +#include "dev-usb.h"
  6467. +
  6468. +#define RB4XX_GPIO_USER_LED 4
  6469. +#define RB4XX_GPIO_RESET_SWITCH 7
  6470. +
  6471. +#define RB4XX_GPIO_CPLD_BASE 32
  6472. +#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1)
  6473. +#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2)
  6474. +#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3)
  6475. +#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4)
  6476. +#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5)
  6477. +
  6478. +#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */
  6479. +#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL)
  6480. +
  6481. +static struct gpio_led rb4xx_leds_gpio[] __initdata = {
  6482. + {
  6483. + .name = "rb4xx:yellow:user",
  6484. + .gpio = RB4XX_GPIO_USER_LED,
  6485. + .active_low = 0,
  6486. + }, {
  6487. + .name = "rb4xx:green:led1",
  6488. + .gpio = RB4XX_GPIO_CPLD_LED1,
  6489. + .active_low = 1,
  6490. + }, {
  6491. + .name = "rb4xx:green:led2",
  6492. + .gpio = RB4XX_GPIO_CPLD_LED2,
  6493. + .active_low = 1,
  6494. + }, {
  6495. + .name = "rb4xx:green:led3",
  6496. + .gpio = RB4XX_GPIO_CPLD_LED3,
  6497. + .active_low = 1,
  6498. + }, {
  6499. + .name = "rb4xx:green:led4",
  6500. + .gpio = RB4XX_GPIO_CPLD_LED4,
  6501. + .active_low = 1,
  6502. + }, {
  6503. + .name = "rb4xx:green:led5",
  6504. + .gpio = RB4XX_GPIO_CPLD_LED5,
  6505. + .active_low = 0,
  6506. + },
  6507. +};
  6508. +
  6509. +static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = {
  6510. + {
  6511. + .desc = "reset_switch",
  6512. + .type = EV_KEY,
  6513. + .code = KEY_RESTART,
  6514. + .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL,
  6515. + .gpio = RB4XX_GPIO_RESET_SWITCH,
  6516. + .active_low = 1,
  6517. + }
  6518. +};
  6519. +
  6520. +static struct platform_device rb4xx_nand_device = {
  6521. + .name = "rb4xx-nand",
  6522. + .id = -1,
  6523. +};
  6524. +
  6525. +static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
  6526. + {
  6527. + .slot = 0,
  6528. + .pin = 1,
  6529. + .irq = AR71XX_PCI_IRQ_DEV2,
  6530. + }, {
  6531. + .slot = 1,
  6532. + .pin = 1,
  6533. + .irq = AR71XX_PCI_IRQ_DEV0,
  6534. + }, {
  6535. + .slot = 1,
  6536. + .pin = 2,
  6537. + .irq = AR71XX_PCI_IRQ_DEV1,
  6538. + }, {
  6539. + .slot = 2,
  6540. + .pin = 1,
  6541. + .irq = AR71XX_PCI_IRQ_DEV1,
  6542. + }, {
  6543. + .slot = 3,
  6544. + .pin = 1,
  6545. + .irq = AR71XX_PCI_IRQ_DEV2,
  6546. + }
  6547. +};
  6548. +
  6549. +#ifdef CONFIG_MTD_PARTITIONS
  6550. +static struct mtd_partition rb4xx_partitions[] = {
  6551. + {
  6552. + .name = "routerboot",
  6553. + .offset = 0,
  6554. + .size = 0x0b000,
  6555. + .mask_flags = MTD_WRITEABLE,
  6556. + }, {
  6557. + .name = "hard_config",
  6558. + .offset = 0x0b000,
  6559. + .size = 0x01000,
  6560. + .mask_flags = MTD_WRITEABLE,
  6561. + }, {
  6562. + .name = "bios",
  6563. + .offset = 0x0d000,
  6564. + .size = 0x02000,
  6565. + .mask_flags = MTD_WRITEABLE,
  6566. + }, {
  6567. + .name = "soft_config",
  6568. + .offset = 0x0f000,
  6569. + .size = 0x01000,
  6570. + }
  6571. +};
  6572. +#define rb4xx_num_partitions ARRAY_SIZE(rb4xx_partitions)
  6573. +#else /* CONFIG_MTD_PARTITIONS */
  6574. +#define rb4xx_partitions NULL
  6575. +#define rb4xx_num_partitions 0
  6576. +#endif /* CONFIG_MTD_PARTITIONS */
  6577. +
  6578. +static struct flash_platform_data rb4xx_flash_data = {
  6579. + .type = "pm25lv512",
  6580. + .parts = rb4xx_partitions,
  6581. + .nr_parts = rb4xx_num_partitions,
  6582. +};
  6583. +
  6584. +static struct rb4xx_cpld_platform_data rb4xx_cpld_data = {
  6585. + .gpio_base = RB4XX_GPIO_CPLD_BASE,
  6586. +};
  6587. +
  6588. +static struct mmc_spi_platform_data rb4xx_mmc_data = {
  6589. + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
  6590. +};
  6591. +
  6592. +static struct spi_board_info rb4xx_spi_info[] = {
  6593. + {
  6594. + .bus_num = 0,
  6595. + .chip_select = 0,
  6596. + .max_speed_hz = 25000000,
  6597. + .modalias = "m25p80",
  6598. + .platform_data = &rb4xx_flash_data,
  6599. + }, {
  6600. + .bus_num = 0,
  6601. + .chip_select = 1,
  6602. + .max_speed_hz = 25000000,
  6603. + .modalias = "spi-rb4xx-cpld",
  6604. + .platform_data = &rb4xx_cpld_data,
  6605. + }
  6606. +};
  6607. +
  6608. +static struct spi_board_info rb4xx_microsd_info[] = {
  6609. + {
  6610. + .bus_num = 0,
  6611. + .chip_select = 2,
  6612. + .max_speed_hz = 25000000,
  6613. + .modalias = "mmc_spi",
  6614. + .platform_data = &rb4xx_mmc_data,
  6615. + }
  6616. +};
  6617. +
  6618. +
  6619. +static struct resource rb4xx_spi_resources[] = {
  6620. + {
  6621. + .start = AR71XX_SPI_BASE,
  6622. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  6623. + .flags = IORESOURCE_MEM,
  6624. + },
  6625. +};
  6626. +
  6627. +static struct platform_device rb4xx_spi_device = {
  6628. + .name = "rb4xx-spi",
  6629. + .id = -1,
  6630. + .resource = rb4xx_spi_resources,
  6631. + .num_resources = ARRAY_SIZE(rb4xx_spi_resources),
  6632. +};
  6633. +
  6634. +static void __init rb4xx_generic_setup(void)
  6635. +{
  6636. + ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN |
  6637. + AR71XX_GPIO_FUNC_SPI_CS2_EN);
  6638. +
  6639. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
  6640. + rb4xx_leds_gpio);
  6641. +
  6642. + ar71xx_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL,
  6643. + ARRAY_SIZE(rb4xx_gpio_keys),
  6644. + rb4xx_gpio_keys);
  6645. +
  6646. + spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
  6647. + platform_device_register(&rb4xx_spi_device);
  6648. + platform_device_register(&rb4xx_nand_device);
  6649. +}
  6650. +
  6651. +static void __init rb411_setup(void)
  6652. +{
  6653. + rb4xx_generic_setup();
  6654. + spi_register_board_info(rb4xx_microsd_info,
  6655. + ARRAY_SIZE(rb4xx_microsd_info));
  6656. +
  6657. + ar71xx_add_device_mdio(0xfffffffc);
  6658. +
  6659. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  6660. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6661. + ar71xx_eth0_data.phy_mask = 0x00000003;
  6662. +
  6663. + ar71xx_add_device_eth(0);
  6664. +
  6665. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  6666. +}
  6667. +
  6668. +MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH",
  6669. + rb411_setup);
  6670. +
  6671. +static void __init rb411u_setup(void)
  6672. +{
  6673. + rb411_setup();
  6674. + ar71xx_add_device_usb();
  6675. +}
  6676. +
  6677. +MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U",
  6678. + rb411u_setup);
  6679. +
  6680. +#define RB433_LAN_PHYMASK BIT(0)
  6681. +#define RB433_WAN_PHYMASK BIT(4)
  6682. +#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK)
  6683. +
  6684. +static void __init rb433_setup(void)
  6685. +{
  6686. + rb4xx_generic_setup();
  6687. + spi_register_board_info(rb4xx_microsd_info,
  6688. + ARRAY_SIZE(rb4xx_microsd_info));
  6689. +
  6690. + ar71xx_add_device_mdio(~RB433_MDIO_PHYMASK);
  6691. +
  6692. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1);
  6693. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6694. + ar71xx_eth0_data.phy_mask = RB433_LAN_PHYMASK;
  6695. +
  6696. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0);
  6697. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6698. + ar71xx_eth1_data.phy_mask = RB433_WAN_PHYMASK;
  6699. +
  6700. + ar71xx_add_device_eth(1);
  6701. + ar71xx_add_device_eth(0);
  6702. +
  6703. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  6704. +}
  6705. +
  6706. +MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH",
  6707. + rb433_setup);
  6708. +
  6709. +static void __init rb433u_setup(void)
  6710. +{
  6711. + rb433_setup();
  6712. + ar71xx_add_device_usb();
  6713. +}
  6714. +
  6715. +MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH",
  6716. + rb433u_setup);
  6717. +
  6718. +#define RB450_LAN_PHYMASK BIT(0)
  6719. +#define RB450_WAN_PHYMASK BIT(4)
  6720. +#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK)
  6721. +
  6722. +static void __init rb450_generic_setup(int gige)
  6723. +{
  6724. + rb4xx_generic_setup();
  6725. + ar71xx_add_device_mdio(~RB450_MDIO_PHYMASK);
  6726. +
  6727. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1);
  6728. + ar71xx_eth0_data.phy_if_mode = (gige) ?
  6729. + PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII;
  6730. + ar71xx_eth0_data.phy_mask = RB450_LAN_PHYMASK;
  6731. +
  6732. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0);
  6733. + ar71xx_eth1_data.phy_if_mode = (gige) ?
  6734. + PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII;
  6735. + ar71xx_eth1_data.phy_mask = RB450_WAN_PHYMASK;
  6736. +
  6737. + ar71xx_add_device_eth(1);
  6738. + ar71xx_add_device_eth(0);
  6739. +}
  6740. +
  6741. +static void __init rb450_setup(void)
  6742. +{
  6743. + rb450_generic_setup(0);
  6744. +}
  6745. +
  6746. +MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450",
  6747. + rb450_setup);
  6748. +
  6749. +static void __init rb450g_setup(void)
  6750. +{
  6751. + rb450_generic_setup(1);
  6752. + spi_register_board_info(rb4xx_microsd_info,
  6753. + ARRAY_SIZE(rb4xx_microsd_info));
  6754. +}
  6755. +
  6756. +MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G",
  6757. + rb450g_setup);
  6758. +
  6759. +static void __init rb493_setup(void)
  6760. +{
  6761. + rb4xx_generic_setup();
  6762. +
  6763. + ar71xx_add_device_mdio(0x3fffff00);
  6764. +
  6765. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  6766. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6767. + ar71xx_eth0_data.speed = SPEED_100;
  6768. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6769. +
  6770. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1);
  6771. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6772. + ar71xx_eth1_data.phy_mask = 0x00000001;
  6773. +
  6774. + ar71xx_add_device_eth(0);
  6775. + ar71xx_add_device_eth(1);
  6776. +
  6777. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  6778. +}
  6779. +
  6780. +MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH",
  6781. + rb493_setup);
  6782. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c
  6783. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100
  6784. +++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-08-24 18:17:23.000000000 +0200
  6785. @@ -0,0 +1,144 @@
  6786. +/*
  6787. + * MikroTik RouterBOARD 750 support
  6788. + *
  6789. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  6790. + *
  6791. + * This program is free software; you can redistribute it and/or modify it
  6792. + * under the terms of the GNU General Public License version 2 as published
  6793. + * by the Free Software Foundation.
  6794. + */
  6795. +
  6796. +#include <linux/platform_device.h>
  6797. +#include <asm/mach-ar71xx/ar71xx.h>
  6798. +#include <asm/mach-ar71xx/mach-rb750.h>
  6799. +
  6800. +#include "machtype.h"
  6801. +#include "devices.h"
  6802. +
  6803. +static struct rb750_led_data rb750_leds[] = {
  6804. + {
  6805. + .name = "rb750:green:act",
  6806. + .mask = RB750_LED_ACT,
  6807. + .active_low = 1,
  6808. + }, {
  6809. + .name = "rb750:green:port1",
  6810. + .mask = RB750_LED_PORT5,
  6811. + .active_low = 1,
  6812. + }, {
  6813. + .name = "rb750:green:port2",
  6814. + .mask = RB750_LED_PORT4,
  6815. + .active_low = 1,
  6816. + }, {
  6817. + .name = "rb750:green:port3",
  6818. + .mask = RB750_LED_PORT3,
  6819. + .active_low = 1,
  6820. + }, {
  6821. + .name = "rb750:green:port4",
  6822. + .mask = RB750_LED_PORT2,
  6823. + .active_low = 1,
  6824. + }, {
  6825. + .name = "rb750:green:port5",
  6826. + .mask = RB750_LED_PORT1,
  6827. + .active_low = 1,
  6828. + }
  6829. +};
  6830. +
  6831. +static struct rb750_led_platform_data rb750_leds_data = {
  6832. + .num_leds = ARRAY_SIZE(rb750_leds),
  6833. + .leds = rb750_leds,
  6834. +};
  6835. +
  6836. +static struct platform_device rb750_leds_device = {
  6837. + .name = "leds-rb750",
  6838. + .dev = {
  6839. + .platform_data = &rb750_leds_data,
  6840. + }
  6841. +};
  6842. +
  6843. +static struct platform_device rb750_nand_device = {
  6844. + .name = "rb750-nand",
  6845. + .id = -1,
  6846. +};
  6847. +
  6848. +int rb750_latch_change(u32 mask_clr, u32 mask_set)
  6849. +{
  6850. + static DEFINE_SPINLOCK(lock);
  6851. + static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE;
  6852. + static u32 latch_oe;
  6853. + static u32 latch_clr;
  6854. + unsigned long flags;
  6855. + u32 t;
  6856. + int ret = 0;
  6857. +
  6858. + spin_lock_irqsave(&lock, flags);
  6859. +
  6860. + if ((mask_clr & BIT(31)) != 0 &&
  6861. + (latch_set & RB750_LVC573_LE) == 0) {
  6862. + goto unlock;
  6863. + }
  6864. +
  6865. + latch_set = (latch_set | mask_set) & ~mask_clr;
  6866. + latch_clr = (latch_clr | mask_clr) & ~mask_set;
  6867. +
  6868. + if (latch_oe == 0)
  6869. + latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE);
  6870. +
  6871. + if (likely(latch_set & RB750_LVC573_LE)) {
  6872. + void __iomem *base = ar71xx_gpio_base;
  6873. +
  6874. + t = __raw_readl(base + GPIO_REG_OE);
  6875. + t |= mask_clr | latch_oe | mask_set;
  6876. +
  6877. + __raw_writel(t, base + GPIO_REG_OE);
  6878. + __raw_writel(latch_clr, base + GPIO_REG_CLEAR);
  6879. + __raw_writel(latch_set, base + GPIO_REG_SET);
  6880. + } else if (mask_clr & RB750_LVC573_LE) {
  6881. + void __iomem *base = ar71xx_gpio_base;
  6882. +
  6883. + latch_oe = __raw_readl(base + GPIO_REG_OE);
  6884. + __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR);
  6885. + /* flush write */
  6886. + __raw_readl(base + GPIO_REG_CLEAR);
  6887. + }
  6888. +
  6889. + ret = 1;
  6890. +
  6891. +unlock:
  6892. + spin_unlock_irqrestore(&lock, flags);
  6893. + return ret;
  6894. +}
  6895. +EXPORT_SYMBOL_GPL(rb750_latch_change);
  6896. +
  6897. +static void __init rb750_setup(void)
  6898. +{
  6899. + ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
  6900. + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
  6901. + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
  6902. + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
  6903. + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
  6904. +
  6905. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  6906. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1);
  6907. +
  6908. + /* WAN port */
  6909. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6910. + ar71xx_eth0_data.speed = SPEED_100;
  6911. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6912. + ar71xx_eth0_data.phy_mask = BIT(4);
  6913. +
  6914. + /* LAN ports */
  6915. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6916. + ar71xx_eth1_data.speed = SPEED_1000;
  6917. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6918. + ar71xx_eth1_data.has_ar7240_switch = 1;
  6919. +
  6920. + ar71xx_add_device_mdio(0x0);
  6921. + ar71xx_add_device_eth(1);
  6922. + ar71xx_add_device_eth(0);
  6923. +
  6924. + platform_device_register(&rb750_leds_device);
  6925. + platform_device_register(&rb750_nand_device);
  6926. +}
  6927. +
  6928. +MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750",
  6929. + rb750_setup);
  6930. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c
  6931. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100
  6932. +++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-08-24 18:17:23.000000000 +0200
  6933. @@ -0,0 +1,151 @@
  6934. +/*
  6935. + * TrendNET TEW-632BRP board support
  6936. + *
  6937. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6938. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6939. + *
  6940. + * This program is free software; you can redistribute it and/or modify it
  6941. + * under the terms of the GNU General Public License version 2 as published
  6942. + * by the Free Software Foundation.
  6943. + */
  6944. +
  6945. +#include <linux/mtd/mtd.h>
  6946. +#include <linux/mtd/partitions.h>
  6947. +
  6948. +#include <asm/mach-ar71xx/ar71xx.h>
  6949. +
  6950. +#include "machtype.h"
  6951. +#include "devices.h"
  6952. +#include "dev-m25p80.h"
  6953. +#include "dev-ar9xxx-wmac.h"
  6954. +#include "dev-gpio-buttons.h"
  6955. +#include "dev-leds-gpio.h"
  6956. +#include "nvram.h"
  6957. +
  6958. +#define TEW_632BRP_GPIO_LED_STATUS 1
  6959. +#define TEW_632BRP_GPIO_LED_WPS 3
  6960. +#define TEW_632BRP_GPIO_LED_WLAN 6
  6961. +#define TEW_632BRP_GPIO_BTN_WPS 12
  6962. +#define TEW_632BRP_GPIO_BTN_RESET 21
  6963. +
  6964. +#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */
  6965. +#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL)
  6966. +
  6967. +#define TEW_632BRP_CONFIG_ADDR 0x1f020000
  6968. +#define TEW_632BRP_CONFIG_SIZE 0x10000
  6969. +
  6970. +#ifdef CONFIG_MTD_PARTITIONS
  6971. +static struct mtd_partition tew_632brp_partitions[] = {
  6972. + {
  6973. + .name = "u-boot",
  6974. + .offset = 0,
  6975. + .size = 0x020000,
  6976. + .mask_flags = MTD_WRITEABLE,
  6977. + }, {
  6978. + .name = "config",
  6979. + .offset = 0x020000,
  6980. + .size = 0x010000,
  6981. + }, {
  6982. + .name = "kernel",
  6983. + .offset = 0x030000,
  6984. + .size = 0x0e0000,
  6985. + }, {
  6986. + .name = "rootfs",
  6987. + .offset = 0x110000,
  6988. + .size = 0x2e0000,
  6989. + }, {
  6990. + .name = "art",
  6991. + .offset = 0x3f0000,
  6992. + .size = 0x010000,
  6993. + .mask_flags = MTD_WRITEABLE,
  6994. + }, {
  6995. + .name = "firmware",
  6996. + .offset = 0x030000,
  6997. + .size = 0x3c0000,
  6998. + }
  6999. +};
  7000. +#endif /* CONFIG_MTD_PARTITIONS */
  7001. +
  7002. +static struct flash_platform_data tew_632brp_flash_data = {
  7003. +#ifdef CONFIG_MTD_PARTITIONS
  7004. + .parts = tew_632brp_partitions,
  7005. + .nr_parts = ARRAY_SIZE(tew_632brp_partitions),
  7006. +#endif
  7007. +};
  7008. +
  7009. +static struct gpio_led tew_632brp_leds_gpio[] __initdata = {
  7010. + {
  7011. + .name = "tew-632brp:green:status",
  7012. + .gpio = TEW_632BRP_GPIO_LED_STATUS,
  7013. + .active_low = 1,
  7014. + }, {
  7015. + .name = "tew-632brp:blue:wps",
  7016. + .gpio = TEW_632BRP_GPIO_LED_WPS,
  7017. + .active_low = 1,
  7018. + }, {
  7019. + .name = "tew-632brp:green:wlan",
  7020. + .gpio = TEW_632BRP_GPIO_LED_WLAN,
  7021. + .active_low = 1,
  7022. + }
  7023. +};
  7024. +
  7025. +static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = {
  7026. + {
  7027. + .desc = "reset",
  7028. + .type = EV_KEY,
  7029. + .code = KEY_RESTART,
  7030. + .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL,
  7031. + .gpio = TEW_632BRP_GPIO_BTN_RESET,
  7032. + }, {
  7033. + .desc = "wps",
  7034. + .type = EV_KEY,
  7035. + .code = KEY_WPS_BUTTON,
  7036. + .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL,
  7037. + .gpio = TEW_632BRP_GPIO_BTN_WPS,
  7038. + }
  7039. +};
  7040. +
  7041. +#define TEW_632BRP_LAN_PHYMASK BIT(0)
  7042. +#define TEW_632BRP_WAN_PHYMASK BIT(4)
  7043. +#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \
  7044. + TEW_632BRP_WAN_PHYMASK))
  7045. +
  7046. +static void __init tew_632brp_setup(void)
  7047. +{
  7048. + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR);
  7049. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7050. + u8 mac[6];
  7051. + u8 *wlan_mac = NULL;
  7052. +
  7053. + if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE,
  7054. + "lan_mac=", mac) == 0) {
  7055. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7056. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  7057. + wlan_mac = mac;
  7058. + }
  7059. +
  7060. + ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK);
  7061. +
  7062. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7063. + ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK;
  7064. +
  7065. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7066. + ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK;
  7067. +
  7068. + ar71xx_add_device_eth(0);
  7069. + ar71xx_add_device_eth(1);
  7070. +
  7071. + ar71xx_add_device_m25p80(&tew_632brp_flash_data);
  7072. +
  7073. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio),
  7074. + tew_632brp_leds_gpio);
  7075. +
  7076. + ar71xx_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL,
  7077. + ARRAY_SIZE(tew_632brp_gpio_keys),
  7078. + tew_632brp_gpio_keys);
  7079. +
  7080. + ar9xxx_add_device_wmac(eeprom, wlan_mac);
  7081. +}
  7082. +
  7083. +MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP",
  7084. + tew_632brp_setup);
  7085. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c
  7086. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c 1970-01-01 01:00:00.000000000 +0100
  7087. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c 2011-08-24 18:17:23.000000000 +0200
  7088. @@ -0,0 +1,166 @@
  7089. +/*
  7090. + * TP-LINK TL-MR3220/3420 board support
  7091. + *
  7092. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  7093. + *
  7094. + * This program is free software; you can redistribute it and/or modify it
  7095. + * under the terms of the GNU General Public License version 2 as published
  7096. + * by the Free Software Foundation.
  7097. + */
  7098. +
  7099. +#include <linux/gpio.h>
  7100. +#include <linux/mtd/mtd.h>
  7101. +#include <linux/mtd/partitions.h>
  7102. +
  7103. +#include <asm/mach-ar71xx/ar71xx.h>
  7104. +
  7105. +#include "machtype.h"
  7106. +#include "devices.h"
  7107. +#include "dev-m25p80.h"
  7108. +#include "dev-ap91-pci.h"
  7109. +#include "dev-gpio-buttons.h"
  7110. +#include "dev-leds-gpio.h"
  7111. +#include "dev-usb.h"
  7112. +
  7113. +#define TL_MR3X20_GPIO_LED_QSS 0
  7114. +#define TL_MR3X20_GPIO_LED_SYSTEM 1
  7115. +#define TL_MR3X20_GPIO_LED_3G 8
  7116. +
  7117. +#define TL_MR3X20_GPIO_BTN_RESET 11
  7118. +#define TL_MR3X20_GPIO_BTN_QSS 12
  7119. +
  7120. +#define TL_MR3X20_GPIO_USB_POWER 6
  7121. +
  7122. +#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */
  7123. +#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL)
  7124. +
  7125. +#ifdef CONFIG_MTD_PARTITIONS
  7126. +static struct mtd_partition tl_mr3x20_partitions[] = {
  7127. + {
  7128. + .name = "u-boot",
  7129. + .offset = 0,
  7130. + .size = 0x020000,
  7131. + .mask_flags = MTD_WRITEABLE,
  7132. + }, {
  7133. + .name = "kernel",
  7134. + .offset = 0x020000,
  7135. + .size = 0x140000,
  7136. + }, {
  7137. + .name = "rootfs",
  7138. + .offset = 0x160000,
  7139. + .size = 0x290000,
  7140. + }, {
  7141. + .name = "art",
  7142. + .offset = 0x3f0000,
  7143. + .size = 0x010000,
  7144. + .mask_flags = MTD_WRITEABLE,
  7145. + }, {
  7146. + .name = "firmware",
  7147. + .offset = 0x020000,
  7148. + .size = 0x3d0000,
  7149. + }
  7150. +};
  7151. +#define tl_mr3x20_num_partitions ARRAY_SIZE(tl_mr3x20_partitions)
  7152. +#else
  7153. +#define tl_mr3x20_partitions NULL
  7154. +#define tl_mr3x20_num_partitions 0
  7155. +#endif /* CONFIG_MTD_PARTITIONS */
  7156. +
  7157. +static struct flash_platform_data tl_mr3x20_flash_data = {
  7158. + .parts = tl_mr3x20_partitions,
  7159. + .nr_parts = tl_mr3x20_num_partitions,
  7160. +};
  7161. +
  7162. +static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = {
  7163. + {
  7164. + .name = "tl-mr3x20:green:system",
  7165. + .gpio = TL_MR3X20_GPIO_LED_SYSTEM,
  7166. + .active_low = 1,
  7167. + }, {
  7168. + .name = "tl-mr3x20:green:qss",
  7169. + .gpio = TL_MR3X20_GPIO_LED_QSS,
  7170. + .active_low = 1,
  7171. + }, {
  7172. + .name = "tl-mr3x20:green:3g",
  7173. + .gpio = TL_MR3X20_GPIO_LED_3G,
  7174. + .active_low = 1,
  7175. + }
  7176. +};
  7177. +
  7178. +static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = {
  7179. + {
  7180. + .desc = "reset",
  7181. + .type = EV_KEY,
  7182. + .code = KEY_RESTART,
  7183. + .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL,
  7184. + .gpio = TL_MR3X20_GPIO_BTN_RESET,
  7185. + .active_low = 1,
  7186. + }, {
  7187. + .desc = "qss",
  7188. + .type = EV_KEY,
  7189. + .code = KEY_WPS_BUTTON,
  7190. + .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL,
  7191. + .gpio = TL_MR3X20_GPIO_BTN_QSS,
  7192. + .active_low = 1,
  7193. + }
  7194. +};
  7195. +
  7196. +static void __init tl_mr3x20_setup(void)
  7197. +{
  7198. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7199. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  7200. +
  7201. + /* enable power for the USB port */
  7202. + gpio_request(TL_MR3X20_GPIO_USB_POWER, "USB power");
  7203. + gpio_direction_output(TL_MR3X20_GPIO_USB_POWER, 1);
  7204. +
  7205. + ar71xx_add_device_m25p80(&tl_mr3x20_flash_data);
  7206. +
  7207. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio),
  7208. + tl_mr3x20_leds_gpio);
  7209. +
  7210. + ar71xx_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL,
  7211. + ARRAY_SIZE(tl_mr3x20_gpio_keys),
  7212. + tl_mr3x20_gpio_keys);
  7213. +
  7214. + ar71xx_eth1_data.has_ar7240_switch = 1;
  7215. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7216. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  7217. +
  7218. + /* WAN port */
  7219. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7220. + ar71xx_eth0_data.speed = SPEED_100;
  7221. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7222. + ar71xx_eth0_data.phy_mask = BIT(4);
  7223. +
  7224. + /* LAN ports */
  7225. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7226. + ar71xx_eth1_data.speed = SPEED_1000;
  7227. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  7228. +
  7229. + ar71xx_add_device_mdio(0x0);
  7230. + ar71xx_add_device_eth(1);
  7231. + ar71xx_add_device_eth(0);
  7232. +
  7233. + ar71xx_add_device_usb();
  7234. +
  7235. + ap91_pci_init(ee, mac);
  7236. +}
  7237. +
  7238. +static void __init tl_mr3220_setup(void)
  7239. +{
  7240. + tl_mr3x20_setup();
  7241. + ap91_pci_setup_wmac_led_pin(1);
  7242. +}
  7243. +
  7244. +MIPS_MACHINE(AR71XX_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220",
  7245. + tl_mr3220_setup);
  7246. +
  7247. +static void __init tl_mr3420_setup(void)
  7248. +{
  7249. + tl_mr3x20_setup();
  7250. + ap91_pci_setup_wmac_led_pin(0);
  7251. +}
  7252. +
  7253. +MIPS_MACHINE(AR71XX_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420",
  7254. + tl_mr3420_setup);
  7255. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c
  7256. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 1970-01-01 01:00:00.000000000 +0100
  7257. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 2011-08-24 18:17:23.000000000 +0200
  7258. @@ -0,0 +1,132 @@
  7259. +/*
  7260. + * TP-LINK TL-WA901ND v2 board support
  7261. + *
  7262. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  7263. + * Copyright (C) 2010 Pieter Hollants <pieter@hollants.com>
  7264. + * Copyright (C) 2011 Jonathan Bennett <jbscience87@gmail.com>
  7265. + *
  7266. + * This program is free software; you can redistribute it and/or modify it
  7267. + * under the terms of the GNU General Public License version 2 as published
  7268. + * by the Free Software Foundation.
  7269. + */
  7270. +
  7271. +#include <linux/mtd/mtd.h>
  7272. +#include <linux/mtd/partitions.h>
  7273. +
  7274. +#include <asm/mach-ar71xx/ar71xx.h>
  7275. +
  7276. +#include "machtype.h"
  7277. +#include "devices.h"
  7278. +#include "dev-m25p80.h"
  7279. +#include "dev-gpio-buttons.h"
  7280. +#include "dev-leds-gpio.h"
  7281. +#include "dev-ar9xxx-wmac.h"
  7282. +
  7283. +#define TL_WA901ND_V2_GPIO_LED_QSS 4
  7284. +#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2
  7285. +#define TL_WA901ND_V2_GPIO_LED_WLAN 9
  7286. +
  7287. +
  7288. +#define TL_WA901ND_V2_GPIO_BTN_RESET 3
  7289. +#define TL_WA901ND_V2_GPIO_BTN_QSS 7
  7290. +
  7291. +#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */
  7292. +#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \
  7293. + (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL)
  7294. +#ifdef CONFIG_MTD_PARTITIONS
  7295. +static struct mtd_partition tl_wa901nd_v2_partitions[] = {
  7296. + {
  7297. + .name = "u-boot",
  7298. + .offset = 0,
  7299. + .size = 0x020000,
  7300. + .mask_flags = MTD_WRITEABLE,
  7301. + }, {
  7302. + .name = "kernel",
  7303. + .offset = 0x020000,
  7304. + .size = 0x140000,
  7305. + }, {
  7306. + .name = "rootfs",
  7307. + .offset = 0x160000,
  7308. + .size = 0x290000,
  7309. + }, {
  7310. + .name = "art",
  7311. + .offset = 0x3f0000,
  7312. + .size = 0x010000,
  7313. + .mask_flags = MTD_WRITEABLE,
  7314. + }, {
  7315. + .name = "firmware",
  7316. + .offset = 0x020000,
  7317. + .size = 0x3d0000,
  7318. + }
  7319. +};
  7320. +#endif /* CONFIG_MTD_PARTITIONS */
  7321. +
  7322. +static struct flash_platform_data tl_wa901nd_v2_flash_data = {
  7323. +#ifdef CONFIG_MTD_PARTITIONS
  7324. + .parts = tl_wa901nd_v2_partitions,
  7325. + .nr_parts = ARRAY_SIZE(tl_wa901nd_v2_partitions),
  7326. +#endif
  7327. +};
  7328. +
  7329. +static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = {
  7330. + {
  7331. + .name = "tl-wa901nd-v2:green:system",
  7332. + .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM,
  7333. + .active_low = 1,
  7334. + }, {
  7335. + .name = "tl-wa901nd-v2:green:qss",
  7336. + .gpio = TL_WA901ND_V2_GPIO_LED_QSS,
  7337. + }, {
  7338. + .name = "tl-wa901nd-v2:green:wlan",
  7339. + .gpio = TL_WA901ND_V2_GPIO_LED_WLAN,
  7340. + .active_low = 1,
  7341. + }
  7342. +};
  7343. +
  7344. +static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = {
  7345. + {
  7346. + .desc = "reset",
  7347. + .type = EV_KEY,
  7348. + .code = KEY_RESTART,
  7349. + .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL,
  7350. + .gpio = TL_WA901ND_V2_GPIO_BTN_RESET,
  7351. + .active_low = 1,
  7352. + }, {
  7353. + .desc = "qss",
  7354. + .type = EV_KEY,
  7355. + .code = KEY_WPS_BUTTON,
  7356. + .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL,
  7357. + .gpio = TL_WA901ND_V2_GPIO_BTN_QSS,
  7358. + .active_low = 1,
  7359. + }
  7360. +};
  7361. +
  7362. +static void __init tl_wa901nd_v2_setup(void)
  7363. +{
  7364. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7365. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7366. +
  7367. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7368. +
  7369. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  7370. + ar71xx_eth0_data.phy_mask = 0x00001000;
  7371. + ar71xx_add_device_mdio(0x0);
  7372. +
  7373. + ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC |
  7374. + RESET_MODULE_GE0_PHY;
  7375. + ar71xx_add_device_eth(0);
  7376. +
  7377. + ar71xx_add_device_m25p80(&tl_wa901nd_v2_flash_data);
  7378. +
  7379. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio),
  7380. + tl_wa901nd_v2_leds_gpio);
  7381. +
  7382. + ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL,
  7383. + ARRAY_SIZE(tl_wa901nd_v2_gpio_keys),
  7384. + tl_wa901nd_v2_gpio_keys);
  7385. +
  7386. + ar9xxx_add_device_wmac(eeprom, mac);
  7387. +}
  7388. +
  7389. +MIPS_MACHINE(AR71XX_MACH_TL_WA901ND_V2, "TL-WA901ND-v2",
  7390. + "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup);
  7391. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c
  7392. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c 1970-01-01 01:00:00.000000000 +0100
  7393. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c 2011-08-24 18:17:23.000000000 +0200
  7394. @@ -0,0 +1,130 @@
  7395. +/*
  7396. + * TP-LINK TL-WA901ND board support
  7397. + *
  7398. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  7399. + * Copyright (C) 2010 Pieter Hollants <pieter@hollants.com>
  7400. + *
  7401. + * This program is free software; you can redistribute it and/or modify it
  7402. + * under the terms of the GNU General Public License version 2 as published
  7403. + * by the Free Software Foundation.
  7404. + */
  7405. +
  7406. +#include <linux/mtd/mtd.h>
  7407. +#include <linux/mtd/partitions.h>
  7408. +
  7409. +#include <asm/mach-ar71xx/ar71xx.h>
  7410. +
  7411. +#include "machtype.h"
  7412. +#include "devices.h"
  7413. +#include "dev-m25p80.h"
  7414. +#include "dev-ap91-pci.h"
  7415. +#include "dev-gpio-buttons.h"
  7416. +#include "dev-leds-gpio.h"
  7417. +
  7418. +#define TL_WA901ND_GPIO_LED_QSS 0
  7419. +#define TL_WA901ND_GPIO_LED_SYSTEM 1
  7420. +
  7421. +#define TL_WA901ND_GPIO_BTN_RESET 11
  7422. +#define TL_WA901ND_GPIO_BTN_QSS 12
  7423. +
  7424. +#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */
  7425. +#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL)
  7426. +
  7427. +#ifdef CONFIG_MTD_PARTITIONS
  7428. +static struct mtd_partition tl_wa901nd_partitions[] = {
  7429. + {
  7430. + .name = "u-boot",
  7431. + .offset = 0,
  7432. + .size = 0x020000,
  7433. + .mask_flags = MTD_WRITEABLE,
  7434. + }, {
  7435. + .name = "kernel",
  7436. + .offset = 0x020000,
  7437. + .size = 0x140000,
  7438. + }, {
  7439. + .name = "rootfs",
  7440. + .offset = 0x160000,
  7441. + .size = 0x290000,
  7442. + }, {
  7443. + .name = "art",
  7444. + .offset = 0x3f0000,
  7445. + .size = 0x010000,
  7446. + .mask_flags = MTD_WRITEABLE,
  7447. + }, {
  7448. + .name = "firmware",
  7449. + .offset = 0x020000,
  7450. + .size = 0x3d0000,
  7451. + }
  7452. +};
  7453. +#endif /* CONFIG_MTD_PARTITIONS */
  7454. +
  7455. +static struct flash_platform_data tl_wa901nd_flash_data = {
  7456. +#ifdef CONFIG_MTD_PARTITIONS
  7457. + .parts = tl_wa901nd_partitions,
  7458. + .nr_parts = ARRAY_SIZE(tl_wa901nd_partitions),
  7459. +#endif
  7460. +};
  7461. +
  7462. +static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = {
  7463. + {
  7464. + .name = "tl-wa901nd:green:system",
  7465. + .gpio = TL_WA901ND_GPIO_LED_SYSTEM,
  7466. + .active_low = 1,
  7467. + }, {
  7468. + .name = "tl-wa901nd:green:qss",
  7469. + .gpio = TL_WA901ND_GPIO_LED_QSS,
  7470. + .active_low = 1,
  7471. + }
  7472. +};
  7473. +
  7474. +static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = {
  7475. + {
  7476. + .desc = "reset",
  7477. + .type = EV_KEY,
  7478. + .code = BTN_0,
  7479. + .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL,
  7480. + .gpio = TL_WA901ND_GPIO_BTN_RESET,
  7481. + .active_low = 1,
  7482. + }, {
  7483. + .desc = "qss",
  7484. + .type = EV_KEY,
  7485. + .code = BTN_1,
  7486. + .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL,
  7487. + .gpio = TL_WA901ND_GPIO_BTN_QSS,
  7488. + .active_low = 1,
  7489. + }
  7490. +};
  7491. +
  7492. +static void __init tl_wa901nd_setup(void)
  7493. +{
  7494. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7495. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  7496. +
  7497. + /*
  7498. + * ar71xx_eth0 would be the WAN port, but is not connected on
  7499. + * the TL-WA901ND. ar71xx_eth1 connects to the internal switch chip,
  7500. + * however we have a single LAN port only.
  7501. + */
  7502. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 0);
  7503. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7504. + ar71xx_eth1_data.speed = SPEED_1000;
  7505. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  7506. + ar71xx_eth1_data.has_ar7240_switch = 1;
  7507. +
  7508. + ar71xx_add_device_mdio(0x0);
  7509. + ar71xx_add_device_eth(1);
  7510. +
  7511. + ar71xx_add_device_m25p80(&tl_wa901nd_flash_data);
  7512. +
  7513. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio),
  7514. + tl_wa901nd_leds_gpio);
  7515. +
  7516. + ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL,
  7517. + ARRAY_SIZE(tl_wa901nd_gpio_keys),
  7518. + tl_wa901nd_gpio_keys);
  7519. +
  7520. + ap91_pci_init(ee, mac);
  7521. +}
  7522. +
  7523. +MIPS_MACHINE(AR71XX_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND",
  7524. + tl_wa901nd_setup);
  7525. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c
  7526. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100
  7527. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-08-24 18:17:23.000000000 +0200
  7528. @@ -0,0 +1,156 @@
  7529. +/*
  7530. + * TP-LINK TL-WR1043ND board support
  7531. + *
  7532. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7533. + *
  7534. + * This program is free software; you can redistribute it and/or modify it
  7535. + * under the terms of the GNU General Public License version 2 as published
  7536. + * by the Free Software Foundation.
  7537. + */
  7538. +
  7539. +#include <linux/mtd/mtd.h>
  7540. +#include <linux/mtd/partitions.h>
  7541. +#include <linux/platform_device.h>
  7542. +#include <linux/rtl8366.h>
  7543. +#include <asm/mach-ar71xx/ar71xx.h>
  7544. +
  7545. +#include "machtype.h"
  7546. +#include "devices.h"
  7547. +#include "dev-m25p80.h"
  7548. +#include "dev-ar9xxx-wmac.h"
  7549. +#include "dev-gpio-buttons.h"
  7550. +#include "dev-leds-gpio.h"
  7551. +#include "dev-usb.h"
  7552. +
  7553. +#define TL_WR1043ND_GPIO_LED_USB 1
  7554. +#define TL_WR1043ND_GPIO_LED_SYSTEM 2
  7555. +#define TL_WR1043ND_GPIO_LED_QSS 5
  7556. +#define TL_WR1043ND_GPIO_LED_WLAN 9
  7557. +
  7558. +#define TL_WR1043ND_GPIO_BTN_RESET 3
  7559. +#define TL_WR1043ND_GPIO_BTN_QSS 7
  7560. +
  7561. +#define TL_WR1043ND_GPIO_RTL8366_SDA 18
  7562. +#define TL_WR1043ND_GPIO_RTL8366_SCK 19
  7563. +
  7564. +#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */
  7565. +#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL)
  7566. +
  7567. +#ifdef CONFIG_MTD_PARTITIONS
  7568. +static struct mtd_partition tl_wr1043nd_partitions[] = {
  7569. + {
  7570. + .name = "u-boot",
  7571. + .offset = 0,
  7572. + .size = 0x020000,
  7573. + .mask_flags = MTD_WRITEABLE,
  7574. + }, {
  7575. + .name = "kernel",
  7576. + .offset = 0x020000,
  7577. + .size = 0x140000,
  7578. + }, {
  7579. + .name = "rootfs",
  7580. + .offset = 0x160000,
  7581. + .size = 0x690000,
  7582. + }, {
  7583. + .name = "art",
  7584. + .offset = 0x7f0000,
  7585. + .size = 0x010000,
  7586. + .mask_flags = MTD_WRITEABLE,
  7587. + }, {
  7588. + .name = "firmware",
  7589. + .offset = 0x020000,
  7590. + .size = 0x7d0000,
  7591. + }
  7592. +};
  7593. +#endif /* CONFIG_MTD_PARTITIONS */
  7594. +
  7595. +static struct flash_platform_data tl_wr1043nd_flash_data = {
  7596. +#ifdef CONFIG_MTD_PARTITIONS
  7597. + .parts = tl_wr1043nd_partitions,
  7598. + .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions),
  7599. +#endif
  7600. +};
  7601. +
  7602. +static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
  7603. + {
  7604. + .name = "tl-wr1043nd:green:usb",
  7605. + .gpio = TL_WR1043ND_GPIO_LED_USB,
  7606. + .active_low = 1,
  7607. + }, {
  7608. + .name = "tl-wr1043nd:green:system",
  7609. + .gpio = TL_WR1043ND_GPIO_LED_SYSTEM,
  7610. + .active_low = 1,
  7611. + }, {
  7612. + .name = "tl-wr1043nd:green:qss",
  7613. + .gpio = TL_WR1043ND_GPIO_LED_QSS,
  7614. + .active_low = 0,
  7615. + }, {
  7616. + .name = "tl-wr1043nd:green:wlan",
  7617. + .gpio = TL_WR1043ND_GPIO_LED_WLAN,
  7618. + .active_low = 1,
  7619. + }
  7620. +};
  7621. +
  7622. +static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = {
  7623. + {
  7624. + .desc = "reset",
  7625. + .type = EV_KEY,
  7626. + .code = KEY_RESTART,
  7627. + .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL,
  7628. + .gpio = TL_WR1043ND_GPIO_BTN_RESET,
  7629. + .active_low = 1,
  7630. + }, {
  7631. + .desc = "qss",
  7632. + .type = EV_KEY,
  7633. + .code = KEY_WPS_BUTTON,
  7634. + .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL,
  7635. + .gpio = TL_WR1043ND_GPIO_BTN_QSS,
  7636. + .active_low = 1,
  7637. + }
  7638. +};
  7639. +
  7640. +static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = {
  7641. + .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA,
  7642. + .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK,
  7643. +};
  7644. +
  7645. +static struct platform_device tl_wr1043nd_rtl8366rb_device = {
  7646. + .name = RTL8366RB_DRIVER_NAME,
  7647. + .id = -1,
  7648. + .dev = {
  7649. + .platform_data = &tl_wr1043nd_rtl8366rb_data,
  7650. + }
  7651. +};
  7652. +
  7653. +static void __init tl_wr1043nd_setup(void)
  7654. +{
  7655. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7656. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7657. +
  7658. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7659. + ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev;
  7660. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7661. + ar71xx_eth0_data.speed = SPEED_1000;
  7662. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7663. + ar71xx_eth0_pll_data.pll_1000 = 0x1a000000;
  7664. +
  7665. + ar71xx_add_device_eth(0);
  7666. +
  7667. + ar71xx_add_device_usb();
  7668. +
  7669. + ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data);
  7670. +
  7671. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio),
  7672. + tl_wr1043nd_leds_gpio);
  7673. +
  7674. + platform_device_register(&tl_wr1043nd_rtl8366rb_device);
  7675. +
  7676. + ar71xx_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL,
  7677. + ARRAY_SIZE(tl_wr1043nd_gpio_keys),
  7678. + tl_wr1043nd_gpio_keys);
  7679. +
  7680. + ar9xxx_add_device_wmac(eeprom, mac);
  7681. +}
  7682. +
  7683. +MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND",
  7684. + tl_wr1043nd_setup);
  7685. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c
  7686. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100
  7687. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-08-24 18:17:23.000000000 +0200
  7688. @@ -0,0 +1,135 @@
  7689. +/*
  7690. + * TP-LINK TL-WR741ND board support
  7691. + *
  7692. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  7693. + *
  7694. + * This program is free software; you can redistribute it and/or modify it
  7695. + * under the terms of the GNU General Public License version 2 as published
  7696. + * by the Free Software Foundation.
  7697. + */
  7698. +
  7699. +#include <linux/mtd/mtd.h>
  7700. +#include <linux/mtd/partitions.h>
  7701. +
  7702. +#include <asm/mach-ar71xx/ar71xx.h>
  7703. +
  7704. +#include "machtype.h"
  7705. +#include "devices.h"
  7706. +#include "dev-m25p80.h"
  7707. +#include "dev-ap91-pci.h"
  7708. +#include "dev-gpio-buttons.h"
  7709. +#include "dev-leds-gpio.h"
  7710. +
  7711. +#define TL_WR741ND_GPIO_LED_QSS 0
  7712. +#define TL_WR741ND_GPIO_LED_SYSTEM 1
  7713. +
  7714. +#define TL_WR741ND_GPIO_BTN_RESET 11
  7715. +#define TL_WR741ND_GPIO_BTN_QSS 12
  7716. +
  7717. +#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */
  7718. +#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL)
  7719. +
  7720. +#ifdef CONFIG_MTD_PARTITIONS
  7721. +static struct mtd_partition tl_wr741nd_partitions[] = {
  7722. + {
  7723. + .name = "u-boot",
  7724. + .offset = 0,
  7725. + .size = 0x020000,
  7726. + .mask_flags = MTD_WRITEABLE,
  7727. + }, {
  7728. + .name = "kernel",
  7729. + .offset = 0x020000,
  7730. + .size = 0x140000,
  7731. + }, {
  7732. + .name = "rootfs",
  7733. + .offset = 0x160000,
  7734. + .size = 0x290000,
  7735. + }, {
  7736. + .name = "art",
  7737. + .offset = 0x3f0000,
  7738. + .size = 0x010000,
  7739. + .mask_flags = MTD_WRITEABLE,
  7740. + }, {
  7741. + .name = "firmware",
  7742. + .offset = 0x020000,
  7743. + .size = 0x3d0000,
  7744. + }
  7745. +};
  7746. +#endif /* CONFIG_MTD_PARTITIONS */
  7747. +
  7748. +static struct flash_platform_data tl_wr741nd_flash_data = {
  7749. +#ifdef CONFIG_MTD_PARTITIONS
  7750. + .parts = tl_wr741nd_partitions,
  7751. + .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions),
  7752. +#endif
  7753. +};
  7754. +
  7755. +static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = {
  7756. + {
  7757. + .name = "tl-wr741nd:green:system",
  7758. + .gpio = TL_WR741ND_GPIO_LED_SYSTEM,
  7759. + .active_low = 1,
  7760. + }, {
  7761. + .name = "tl-wr741nd:green:qss",
  7762. + .gpio = TL_WR741ND_GPIO_LED_QSS,
  7763. + .active_low = 1,
  7764. + }
  7765. +};
  7766. +
  7767. +static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = {
  7768. + {
  7769. + .desc = "reset",
  7770. + .type = EV_KEY,
  7771. + .code = KEY_RESTART,
  7772. + .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL,
  7773. + .gpio = TL_WR741ND_GPIO_BTN_RESET,
  7774. + .active_low = 1,
  7775. + }, {
  7776. + .desc = "qss",
  7777. + .type = EV_KEY,
  7778. + .code = KEY_WPS_BUTTON,
  7779. + .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL,
  7780. + .gpio = TL_WR741ND_GPIO_BTN_QSS,
  7781. + .active_low = 1,
  7782. + }
  7783. +};
  7784. +
  7785. +static void __init tl_wr741nd_setup(void)
  7786. +{
  7787. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7788. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  7789. +
  7790. + ar71xx_add_device_m25p80(&tl_wr741nd_flash_data);
  7791. +
  7792. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio),
  7793. + tl_wr741nd_leds_gpio);
  7794. +
  7795. + ar71xx_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL,
  7796. + ARRAY_SIZE(tl_wr741nd_gpio_keys),
  7797. + tl_wr741nd_gpio_keys);
  7798. +
  7799. + ar71xx_eth1_data.has_ar7240_switch = 1;
  7800. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7801. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  7802. +
  7803. + /* WAN port */
  7804. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7805. + ar71xx_eth0_data.speed = SPEED_100;
  7806. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7807. + ar71xx_eth0_data.phy_mask = BIT(4);
  7808. +
  7809. + /* LAN ports */
  7810. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7811. + ar71xx_eth1_data.speed = SPEED_1000;
  7812. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  7813. +
  7814. + ar71xx_add_device_mdio(0x0);
  7815. + ar71xx_add_device_eth(1);
  7816. + ar71xx_add_device_eth(0);
  7817. +
  7818. + ap91_pci_setup_wmac_led_pin(1);
  7819. +
  7820. + ap91_pci_init(ee, mac);
  7821. +}
  7822. +MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND",
  7823. + tl_wr741nd_setup);
  7824. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c
  7825. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100
  7826. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-08-24 18:17:23.000000000 +0200
  7827. @@ -0,0 +1,144 @@
  7828. +/*
  7829. + * TP-LINK TL-WR841N board support
  7830. + *
  7831. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7832. + *
  7833. + * This program is free software; you can redistribute it and/or modify it
  7834. + * under the terms of the GNU General Public License version 2 as published
  7835. + * by the Free Software Foundation.
  7836. + */
  7837. +
  7838. +#include <linux/mtd/mtd.h>
  7839. +#include <linux/mtd/partitions.h>
  7840. +
  7841. +#include <asm/mach-ar71xx/ar71xx.h>
  7842. +
  7843. +#include "machtype.h"
  7844. +#include "devices.h"
  7845. +#include "dev-dsa.h"
  7846. +#include "dev-m25p80.h"
  7847. +#include "dev-gpio-buttons.h"
  7848. +#include "dev-pb42-pci.h"
  7849. +#include "dev-leds-gpio.h"
  7850. +
  7851. +#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2
  7852. +#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4
  7853. +#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5
  7854. +
  7855. +#define TL_WR841ND_V1_GPIO_BTN_RESET 3
  7856. +#define TL_WR841ND_V1_GPIO_BTN_QSS 7
  7857. +
  7858. +#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */
  7859. +#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \
  7860. + (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL)
  7861. +
  7862. +#ifdef CONFIG_MTD_PARTITIONS
  7863. +static struct mtd_partition tl_wr841n_v1_partitions[] = {
  7864. + {
  7865. + .name = "redboot",
  7866. + .offset = 0,
  7867. + .size = 0x020000,
  7868. + .mask_flags = MTD_WRITEABLE,
  7869. + }, {
  7870. + .name = "kernel",
  7871. + .offset = 0x020000,
  7872. + .size = 0x140000,
  7873. + }, {
  7874. + .name = "rootfs",
  7875. + .offset = 0x160000,
  7876. + .size = 0x280000,
  7877. + }, {
  7878. + .name = "config",
  7879. + .offset = 0x3e0000,
  7880. + .size = 0x020000,
  7881. + .mask_flags = MTD_WRITEABLE,
  7882. + }, {
  7883. + .name = "firmware",
  7884. + .offset = 0x020000,
  7885. + .size = 0x3c0000,
  7886. + }
  7887. +};
  7888. +#endif /* CONFIG_MTD_PARTITIONS */
  7889. +
  7890. +static struct flash_platform_data tl_wr841n_v1_flash_data = {
  7891. +#ifdef CONFIG_MTD_PARTITIONS
  7892. + .parts = tl_wr841n_v1_partitions,
  7893. + .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions),
  7894. +#endif
  7895. +};
  7896. +
  7897. +static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = {
  7898. + {
  7899. + .name = "tl-wr841n:green:system",
  7900. + .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM,
  7901. + .active_low = 1,
  7902. + }, {
  7903. + .name = "tl-wr841n:red:qss",
  7904. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED,
  7905. + }, {
  7906. + .name = "tl-wr841n:green:qss",
  7907. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN,
  7908. + }
  7909. +};
  7910. +
  7911. +static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = {
  7912. + {
  7913. + .desc = "reset",
  7914. + .type = EV_KEY,
  7915. + .code = KEY_RESTART,
  7916. + .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL,
  7917. + .gpio = TL_WR841ND_V1_GPIO_BTN_RESET,
  7918. + .active_low = 1,
  7919. + }, {
  7920. + .desc = "qss",
  7921. + .type = EV_KEY,
  7922. + .code = KEY_WPS_BUTTON,
  7923. + .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL,
  7924. + .gpio = TL_WR841ND_V1_GPIO_BTN_QSS,
  7925. + .active_low = 1,
  7926. + }
  7927. +};
  7928. +
  7929. +static struct dsa_chip_data tl_wr841n_v1_dsa_chip = {
  7930. + .port_names[0] = "wan",
  7931. + .port_names[1] = "lan1",
  7932. + .port_names[2] = "lan2",
  7933. + .port_names[3] = "lan3",
  7934. + .port_names[4] = "lan4",
  7935. + .port_names[5] = "cpu",
  7936. +};
  7937. +
  7938. +static struct dsa_platform_data tl_wr841n_v1_dsa_data = {
  7939. + .nr_chips = 1,
  7940. + .chip = &tl_wr841n_v1_dsa_chip,
  7941. +};
  7942. +
  7943. +static void __init tl_wr841n_v1_setup(void)
  7944. +{
  7945. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  7946. +
  7947. + ar71xx_add_device_mdio(0x0);
  7948. +
  7949. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  7950. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7951. + ar71xx_eth0_data.speed = SPEED_100;
  7952. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7953. +
  7954. + ar71xx_add_device_eth(0);
  7955. +
  7956. + ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data);
  7957. +
  7958. + ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data);
  7959. +
  7960. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio),
  7961. + tl_wr841n_v1_leds_gpio);
  7962. +
  7963. + ar71xx_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL,
  7964. + ARRAY_SIZE(tl_wr841n_v1_gpio_keys),
  7965. + tl_wr841n_v1_gpio_keys);
  7966. +
  7967. + pb42_pci_init();
  7968. +}
  7969. +
  7970. +MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1",
  7971. + tl_wr841n_v1_setup);
  7972. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c
  7973. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100
  7974. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-08-24 18:17:23.000000000 +0200
  7975. @@ -0,0 +1,147 @@
  7976. +/*
  7977. + * TP-LINK TL-WR941ND board support
  7978. + *
  7979. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  7980. + *
  7981. + * This program is free software; you can redistribute it and/or modify it
  7982. + * under the terms of the GNU General Public License version 2 as published
  7983. + * by the Free Software Foundation.
  7984. + */
  7985. +
  7986. +#include <linux/mtd/mtd.h>
  7987. +#include <linux/mtd/partitions.h>
  7988. +
  7989. +#include <asm/mach-ar71xx/ar71xx.h>
  7990. +
  7991. +#include "machtype.h"
  7992. +#include "devices.h"
  7993. +#include "dev-dsa.h"
  7994. +#include "dev-m25p80.h"
  7995. +#include "dev-ar9xxx-wmac.h"
  7996. +#include "dev-gpio-buttons.h"
  7997. +#include "dev-leds-gpio.h"
  7998. +
  7999. +#define TL_WR941ND_GPIO_LED_SYSTEM 2
  8000. +#define TL_WR941ND_GPIO_LED_QSS_RED 4
  8001. +#define TL_WR941ND_GPIO_LED_QSS_GREEN 5
  8002. +#define TL_WR941ND_GPIO_LED_WLAN 9
  8003. +
  8004. +#define TL_WR941ND_GPIO_BTN_RESET 3
  8005. +#define TL_WR941ND_GPIO_BTN_QSS 7
  8006. +
  8007. +#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */
  8008. +#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL)
  8009. +
  8010. +#ifdef CONFIG_MTD_PARTITIONS
  8011. +static struct mtd_partition tl_wr941nd_partitions[] = {
  8012. + {
  8013. + .name = "u-boot",
  8014. + .offset = 0,
  8015. + .size = 0x020000,
  8016. + .mask_flags = MTD_WRITEABLE,
  8017. + }, {
  8018. + .name = "kernel",
  8019. + .offset = 0x020000,
  8020. + .size = 0x140000,
  8021. + }, {
  8022. + .name = "rootfs",
  8023. + .offset = 0x160000,
  8024. + .size = 0x290000,
  8025. + }, {
  8026. + .name = "art",
  8027. + .offset = 0x3f0000,
  8028. + .size = 0x010000,
  8029. + .mask_flags = MTD_WRITEABLE,
  8030. + }, {
  8031. + .name = "firmware",
  8032. + .offset = 0x020000,
  8033. + .size = 0x3d0000,
  8034. + }
  8035. +};
  8036. +#endif /* CONFIG_MTD_PARTITIONS */
  8037. +
  8038. +static struct flash_platform_data tl_wr941nd_flash_data = {
  8039. +#ifdef CONFIG_MTD_PARTITIONS
  8040. + .parts = tl_wr941nd_partitions,
  8041. + .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions),
  8042. +#endif
  8043. +};
  8044. +
  8045. +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = {
  8046. + {
  8047. + .name = "tl-wr941nd:green:system",
  8048. + .gpio = TL_WR941ND_GPIO_LED_SYSTEM,
  8049. + .active_low = 1,
  8050. + }, {
  8051. + .name = "tl-wr941nd:red:qss",
  8052. + .gpio = TL_WR941ND_GPIO_LED_QSS_RED,
  8053. + }, {
  8054. + .name = "tl-wr941nd:green:qss",
  8055. + .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN,
  8056. + }, {
  8057. + .name = "tl-wr941nd:green:wlan",
  8058. + .gpio = TL_WR941ND_GPIO_LED_WLAN,
  8059. + .active_low = 1,
  8060. + }
  8061. +};
  8062. +
  8063. +static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = {
  8064. + {
  8065. + .desc = "reset",
  8066. + .type = EV_KEY,
  8067. + .code = KEY_RESTART,
  8068. + .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL,
  8069. + .gpio = TL_WR941ND_GPIO_BTN_RESET,
  8070. + .active_low = 1,
  8071. + }, {
  8072. + .desc = "qss",
  8073. + .type = EV_KEY,
  8074. + .code = KEY_WPS_BUTTON,
  8075. + .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL,
  8076. + .gpio = TL_WR941ND_GPIO_BTN_QSS,
  8077. + .active_low = 1,
  8078. + }
  8079. +};
  8080. +
  8081. +static struct dsa_chip_data tl_wr941nd_dsa_chip = {
  8082. + .port_names[0] = "wan",
  8083. + .port_names[1] = "lan1",
  8084. + .port_names[2] = "lan2",
  8085. + .port_names[3] = "lan3",
  8086. + .port_names[4] = "lan4",
  8087. + .port_names[5] = "cpu",
  8088. +};
  8089. +
  8090. +static struct dsa_platform_data tl_wr941nd_dsa_data = {
  8091. + .nr_chips = 1,
  8092. + .chip = &tl_wr941nd_dsa_chip,
  8093. +};
  8094. +
  8095. +static void __init tl_wr941nd_setup(void)
  8096. +{
  8097. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  8098. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  8099. +
  8100. + ar71xx_add_device_mdio(0x0);
  8101. +
  8102. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  8103. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8104. + ar71xx_eth0_data.speed = SPEED_100;
  8105. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  8106. +
  8107. + ar71xx_add_device_eth(0);
  8108. + ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data);
  8109. +
  8110. + ar71xx_add_device_m25p80(&tl_wr941nd_flash_data);
  8111. +
  8112. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio),
  8113. + tl_wr941nd_leds_gpio);
  8114. +
  8115. + ar71xx_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL,
  8116. + ARRAY_SIZE(tl_wr941nd_gpio_keys),
  8117. + tl_wr941nd_gpio_keys);
  8118. + ar9xxx_add_device_wmac(eeprom, mac);
  8119. +}
  8120. +
  8121. +MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND",
  8122. + tl_wr941nd_setup);
  8123. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c
  8124. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100
  8125. +++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-08-24 18:17:23.000000000 +0200
  8126. @@ -0,0 +1,333 @@
  8127. +/*
  8128. + * Ubiquiti RouterStation support
  8129. + *
  8130. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8131. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8132. + * Copyright (C) 2008 Ubiquiti <support@ubnt.com>
  8133. + *
  8134. + * This program is free software; you can redistribute it and/or modify it
  8135. + * under the terms of the GNU General Public License version 2 as published
  8136. + * by the Free Software Foundation.
  8137. + */
  8138. +
  8139. +#include <asm/mach-ar71xx/ar71xx.h>
  8140. +
  8141. +#include "machtype.h"
  8142. +#include "devices.h"
  8143. +#include "dev-m25p80.h"
  8144. +#include "dev-ap91-pci.h"
  8145. +#include "dev-gpio-buttons.h"
  8146. +#include "dev-pb42-pci.h"
  8147. +#include "dev-leds-gpio.h"
  8148. +#include "dev-usb.h"
  8149. +
  8150. +#define UBNT_RS_GPIO_LED_RF 2
  8151. +#define UBNT_RS_GPIO_SW4 8
  8152. +
  8153. +#define UBNT_LS_SR71_GPIO_LED_D25 0
  8154. +#define UBNT_LS_SR71_GPIO_LED_D26 1
  8155. +#define UBNT_LS_SR71_GPIO_LED_D24 2
  8156. +#define UBNT_LS_SR71_GPIO_LED_D23 4
  8157. +#define UBNT_LS_SR71_GPIO_LED_D22 5
  8158. +#define UBNT_LS_SR71_GPIO_LED_D27 6
  8159. +#define UBNT_LS_SR71_GPIO_LED_D28 7
  8160. +
  8161. +#define UBNT_M_GPIO_LED_L1 0
  8162. +#define UBNT_M_GPIO_LED_L2 1
  8163. +#define UBNT_M_GPIO_LED_L3 11
  8164. +#define UBNT_M_GPIO_LED_L4 7
  8165. +#define UBNT_M_GPIO_BTN_RESET 12
  8166. +
  8167. +#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */
  8168. +#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL)
  8169. +
  8170. +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = {
  8171. + {
  8172. + .name = "ubnt:green:rf",
  8173. + .gpio = UBNT_RS_GPIO_LED_RF,
  8174. + .active_low = 0,
  8175. + }
  8176. +};
  8177. +
  8178. +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = {
  8179. + {
  8180. + .name = "ubnt:green:d22",
  8181. + .gpio = UBNT_LS_SR71_GPIO_LED_D22,
  8182. + .active_low = 0,
  8183. + }, {
  8184. + .name = "ubnt:green:d23",
  8185. + .gpio = UBNT_LS_SR71_GPIO_LED_D23,
  8186. + .active_low = 0,
  8187. + }, {
  8188. + .name = "ubnt:green:d24",
  8189. + .gpio = UBNT_LS_SR71_GPIO_LED_D24,
  8190. + .active_low = 0,
  8191. + }, {
  8192. + .name = "ubnt:red:d25",
  8193. + .gpio = UBNT_LS_SR71_GPIO_LED_D25,
  8194. + .active_low = 0,
  8195. + }, {
  8196. + .name = "ubnt:red:d26",
  8197. + .gpio = UBNT_LS_SR71_GPIO_LED_D26,
  8198. + .active_low = 0,
  8199. + }, {
  8200. + .name = "ubnt:green:d27",
  8201. + .gpio = UBNT_LS_SR71_GPIO_LED_D27,
  8202. + .active_low = 0,
  8203. + }, {
  8204. + .name = "ubnt:green:d28",
  8205. + .gpio = UBNT_LS_SR71_GPIO_LED_D28,
  8206. + .active_low = 0,
  8207. + }
  8208. +};
  8209. +
  8210. +static struct gpio_led ubnt_m_leds_gpio[] __initdata = {
  8211. + {
  8212. + .name = "ubnt:red:link1",
  8213. + .gpio = UBNT_M_GPIO_LED_L1,
  8214. + .active_low = 0,
  8215. + }, {
  8216. + .name = "ubnt:orange:link2",
  8217. + .gpio = UBNT_M_GPIO_LED_L2,
  8218. + .active_low = 0,
  8219. + }, {
  8220. + .name = "ubnt:green:link3",
  8221. + .gpio = UBNT_M_GPIO_LED_L3,
  8222. + .active_low = 0,
  8223. + }, {
  8224. + .name = "ubnt:green:link4",
  8225. + .gpio = UBNT_M_GPIO_LED_L4,
  8226. + .active_low = 0,
  8227. + }
  8228. +};
  8229. +
  8230. +static struct gpio_keys_button ubnt_gpio_keys[] __initdata = {
  8231. + {
  8232. + .desc = "sw4",
  8233. + .type = EV_KEY,
  8234. + .code = KEY_RESTART,
  8235. + .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL,
  8236. + .gpio = UBNT_RS_GPIO_SW4,
  8237. + .active_low = 1,
  8238. + }
  8239. +};
  8240. +
  8241. +static struct gpio_keys_button ubnt_m_gpio_keys[] __initdata = {
  8242. + {
  8243. + .desc = "reset",
  8244. + .type = EV_KEY,
  8245. + .code = KEY_RESTART,
  8246. + .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL,
  8247. + .gpio = UBNT_M_GPIO_BTN_RESET,
  8248. + .active_low = 1,
  8249. + }
  8250. +};
  8251. +
  8252. +static void __init ubnt_generic_setup(void)
  8253. +{
  8254. + ar71xx_add_device_m25p80(NULL);
  8255. +
  8256. + ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL,
  8257. + ARRAY_SIZE(ubnt_gpio_keys),
  8258. + ubnt_gpio_keys);
  8259. +
  8260. + pb42_pci_init();
  8261. +}
  8262. +
  8263. +/*
  8264. + * There is Secondary MAC address duplicate problem with some UBNT HW batches.
  8265. + * Do not increase Secondary MAC address by 1 but do workaround
  8266. + * with 'Locally Administrated' bit.
  8267. + */
  8268. +static void __init ubnt_init_secondary_mac(unsigned char *mac_base)
  8269. +{
  8270. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_base, 0);
  8271. + ar71xx_eth1_data.mac_addr[0] |= 0x02;
  8272. +}
  8273. +
  8274. +#define UBNT_RS_WAN_PHYMASK BIT(20)
  8275. +#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  8276. +
  8277. +static void __init ubnt_rs_setup(void)
  8278. +{
  8279. + ubnt_generic_setup();
  8280. +
  8281. + ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK));
  8282. +
  8283. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  8284. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  8285. + ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK;
  8286. +
  8287. + ubnt_init_secondary_mac(ar71xx_mac_base);
  8288. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8289. + ar71xx_eth1_data.speed = SPEED_100;
  8290. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  8291. +
  8292. + ar71xx_add_device_eth(0);
  8293. + ar71xx_add_device_eth(1);
  8294. +
  8295. + ar71xx_add_device_usb();
  8296. +
  8297. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  8298. + ubnt_rs_leds_gpio);
  8299. +}
  8300. +
  8301. +MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation",
  8302. + ubnt_rs_setup);
  8303. +
  8304. +#define UBNT_RSPRO_WAN_PHYMASK BIT(4)
  8305. +#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
  8306. +
  8307. +static void __init ubnt_rspro_setup(void)
  8308. +{
  8309. + ubnt_generic_setup();
  8310. +
  8311. + ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK |
  8312. + UBNT_RSPRO_LAN_PHYMASK));
  8313. +
  8314. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  8315. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  8316. + ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK;
  8317. +
  8318. + ubnt_init_secondary_mac(ar71xx_mac_base);
  8319. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  8320. + ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK;
  8321. + ar71xx_eth1_data.speed = SPEED_1000;
  8322. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  8323. +
  8324. + ar71xx_add_device_eth(0);
  8325. + ar71xx_add_device_eth(1);
  8326. +
  8327. + ar71xx_add_device_usb();
  8328. +
  8329. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  8330. + ubnt_rs_leds_gpio);
  8331. +}
  8332. +
  8333. +MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro",
  8334. + ubnt_rspro_setup);
  8335. +
  8336. +static void __init ubnt_lsx_setup(void)
  8337. +{
  8338. + ubnt_generic_setup();
  8339. +}
  8340. +
  8341. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup);
  8342. +
  8343. +#define UBNT_LSSR71_PHY_MASK BIT(1)
  8344. +
  8345. +static void __init ubnt_lssr71_setup(void)
  8346. +{
  8347. + ubnt_generic_setup();
  8348. +
  8349. + ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK);
  8350. +
  8351. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  8352. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  8353. + ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK;
  8354. +
  8355. + ar71xx_add_device_eth(0);
  8356. +
  8357. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio),
  8358. + ubnt_ls_sr71_leds_gpio);
  8359. +}
  8360. +
  8361. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71",
  8362. + ubnt_lssr71_setup);
  8363. +
  8364. +#define UBNT_M_WAN_PHYMASK BIT(4)
  8365. +
  8366. +static void __init ubnt_m_setup(void)
  8367. +{
  8368. + u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000);
  8369. + u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN);
  8370. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  8371. +
  8372. + ar71xx_add_device_m25p80(NULL);
  8373. +
  8374. + ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK);
  8375. +
  8376. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0);
  8377. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 0);
  8378. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8379. + ar71xx_eth0_data.speed = SPEED_100;
  8380. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  8381. + ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK;
  8382. +
  8383. + ar71xx_add_device_eth(0);
  8384. +
  8385. + ap91_pci_init(ee, NULL);
  8386. +
  8387. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio),
  8388. + ubnt_m_leds_gpio);
  8389. +
  8390. + ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL,
  8391. + ARRAY_SIZE(ubnt_m_gpio_keys),
  8392. + ubnt_m_gpio_keys);
  8393. +}
  8394. +
  8395. +static void __init ubnt_rocket_m_setup(void)
  8396. +{
  8397. + ubnt_m_setup();
  8398. + ar71xx_add_device_usb();
  8399. +}
  8400. +
  8401. +MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M",
  8402. + ubnt_m_setup);
  8403. +MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M",
  8404. + ubnt_rocket_m_setup);
  8405. +
  8406. +/* TODO detect the second ethernet port and use one
  8407. + init function for all Ubiquiti MIMO series products */
  8408. +static void __init ubnt_nano_m_setup(void)
  8409. +{
  8410. + ubnt_m_setup();
  8411. +
  8412. + ar71xx_eth1_data.has_ar7240_switch = 1;
  8413. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8414. + ar71xx_eth1_data.speed = SPEED_1000;
  8415. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  8416. +
  8417. + ar71xx_add_device_eth(1);
  8418. +}
  8419. +
  8420. +MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M",
  8421. + ubnt_nano_m_setup);
  8422. +
  8423. +static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = {
  8424. + {
  8425. + .name = "ubnt:orange:dome",
  8426. + .gpio = 1,
  8427. + .active_low = 0,
  8428. + }, {
  8429. + .name = "ubnt:green:dome",
  8430. + .gpio = 0,
  8431. + .active_low = 0,
  8432. + }
  8433. +};
  8434. +
  8435. +static void __init ubnt_unifi_setup(void)
  8436. +{
  8437. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  8438. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  8439. +
  8440. + ar71xx_add_device_m25p80(NULL);
  8441. +
  8442. + ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK);
  8443. +
  8444. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  8445. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8446. + ar71xx_eth0_data.speed = SPEED_100;
  8447. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  8448. + ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK;
  8449. +
  8450. + ar71xx_add_device_eth(0);
  8451. +
  8452. + ap91_pci_init(ee, NULL);
  8453. +
  8454. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio),
  8455. + ubnt_unifi_leds_gpio);
  8456. +}
  8457. +
  8458. +MIPS_MACHINE(AR71XX_MACH_UBNT_UNIFI, "UBNT-XM", "Ubiquiti UniFi",
  8459. + ubnt_unifi_setup);
  8460. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c
  8461. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100
  8462. +++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-08-24 18:17:23.000000000 +0200
  8463. @@ -0,0 +1,290 @@
  8464. +/*
  8465. + * Netgear WNDR3700 board support
  8466. + *
  8467. + * Copyright (C) 2009 Marco Porsch
  8468. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  8469. + *
  8470. + * This program is free software; you can redistribute it and/or modify it
  8471. + * under the terms of the GNU General Public License version 2 as published
  8472. + * by the Free Software Foundation.
  8473. + */
  8474. +
  8475. +#include <linux/platform_device.h>
  8476. +#include <linux/mtd/mtd.h>
  8477. +#include <linux/mtd/partitions.h>
  8478. +#include <linux/delay.h>
  8479. +#include <linux/rtl8366.h>
  8480. +
  8481. +#include <asm/mach-ar71xx/ar71xx.h>
  8482. +
  8483. +#include "machtype.h"
  8484. +#include "devices.h"
  8485. +#include "dev-m25p80.h"
  8486. +#include "dev-ap94-pci.h"
  8487. +#include "dev-gpio-buttons.h"
  8488. +#include "dev-leds-gpio.h"
  8489. +#include "dev-usb.h"
  8490. +
  8491. +#define WNDR3700_GPIO_LED_WPS_ORANGE 0
  8492. +#define WNDR3700_GPIO_LED_POWER_ORANGE 1
  8493. +#define WNDR3700_GPIO_LED_POWER_GREEN 2
  8494. +#define WNDR3700_GPIO_LED_WPS_GREEN 4
  8495. +#define WNDR3700_GPIO_LED_WAN_GREEN 6
  8496. +
  8497. +#define WNDR3700_GPIO_BTN_WPS 3
  8498. +#define WNDR3700_GPIO_BTN_RESET 8
  8499. +#define WNDR3700_GPIO_BTN_WIFI 11
  8500. +
  8501. +#define WNDR3700_GPIO_RTL8366_SDA 5
  8502. +#define WNDR3700_GPIO_RTL8366_SCK 7
  8503. +
  8504. +#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */
  8505. +#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL)
  8506. +
  8507. +#define WNDR3700_ETH0_MAC_OFFSET 0
  8508. +#define WNDR3700_ETH1_MAC_OFFSET 0x6
  8509. +
  8510. +#define WNDR3700_WMAC0_MAC_OFFSET 0
  8511. +#define WNDR3700_WMAC1_MAC_OFFSET 0xc
  8512. +#define WNDR3700_CALDATA0_OFFSET 0x1000
  8513. +#define WNDR3700_CALDATA1_OFFSET 0x5000
  8514. +
  8515. +#ifdef CONFIG_MTD_PARTITIONS
  8516. +static struct mtd_partition wndr3700_partitions[] = {
  8517. + {
  8518. + .name = "uboot",
  8519. + .offset = 0,
  8520. + .size = 0x050000,
  8521. + .mask_flags = MTD_WRITEABLE,
  8522. + }, {
  8523. + .name = "env",
  8524. + .offset = 0x050000,
  8525. + .size = 0x020000,
  8526. + .mask_flags = MTD_WRITEABLE,
  8527. + }, {
  8528. + .name = "rootfs",
  8529. + .offset = 0x070000,
  8530. + .size = 0x720000,
  8531. + }, {
  8532. + .name = "config",
  8533. + .offset = 0x790000,
  8534. + .size = 0x010000,
  8535. + .mask_flags = MTD_WRITEABLE,
  8536. + }, {
  8537. + .name = "config_bak",
  8538. + .offset = 0x7a0000,
  8539. + .size = 0x010000,
  8540. + .mask_flags = MTD_WRITEABLE,
  8541. + }, {
  8542. + .name = "pot",
  8543. + .offset = 0x7b0000,
  8544. + .size = 0x010000,
  8545. + .mask_flags = MTD_WRITEABLE,
  8546. + }, {
  8547. + .name = "traffic_meter",
  8548. + .offset = 0x7c0000,
  8549. + .size = 0x010000,
  8550. + .mask_flags = MTD_WRITEABLE,
  8551. + }, {
  8552. + .name = "language",
  8553. + .offset = 0x7d0000,
  8554. + .size = 0x020000,
  8555. + .mask_flags = MTD_WRITEABLE,
  8556. + }, {
  8557. + .name = "caldata",
  8558. + .offset = 0x7f0000,
  8559. + .size = 0x010000,
  8560. + .mask_flags = MTD_WRITEABLE,
  8561. + }
  8562. +};
  8563. +
  8564. +static struct mtd_partition wndr3700v2_partitions[] = {
  8565. + {
  8566. + .name = "uboot",
  8567. + .offset = 0,
  8568. + .size = 0x050000,
  8569. + .mask_flags = MTD_WRITEABLE,
  8570. + }, {
  8571. + .name = "env",
  8572. + .offset = 0x050000,
  8573. + .size = 0x020000,
  8574. + .mask_flags = MTD_WRITEABLE,
  8575. + }, {
  8576. + .name = "rootfs",
  8577. + .offset = 0x070000,
  8578. + .size = 0xe40000,
  8579. + }, {
  8580. + .name = "config",
  8581. + .offset = 0xeb0000,
  8582. + .size = 0x010000,
  8583. + .mask_flags = MTD_WRITEABLE,
  8584. + }, {
  8585. + .name = "config_bak",
  8586. + .offset = 0xec0000,
  8587. + .size = 0x010000,
  8588. + .mask_flags = MTD_WRITEABLE,
  8589. + }, {
  8590. + .name = "pot",
  8591. + .offset = 0xed0000,
  8592. + .size = 0x010000,
  8593. + .mask_flags = MTD_WRITEABLE,
  8594. + }, {
  8595. + .name = "traffic_meter",
  8596. + .offset = 0xee0000,
  8597. + .size = 0x010000,
  8598. + .mask_flags = MTD_WRITEABLE,
  8599. + }, {
  8600. + .name = "language",
  8601. + .offset = 0xef0000,
  8602. + .size = 0x100000,
  8603. + .mask_flags = MTD_WRITEABLE,
  8604. + }, {
  8605. + .name = "caldata",
  8606. + .offset = 0xff0000,
  8607. + .size = 0x010000,
  8608. + .mask_flags = MTD_WRITEABLE,
  8609. + }
  8610. +};
  8611. +#define wndr3700_num_partitions ARRAY_SIZE(wndr3700_partitions)
  8612. +#define wndr3700v2_num_partitions ARRAY_SIZE(wndr3700v2_partitions)
  8613. +#else
  8614. +#define wndr3700_partitions NULL
  8615. +#define wndr3700_num_partitions 0
  8616. +#define wndr3700v2_partitions NULL
  8617. +#define wndr3700v2_num_partitions 0
  8618. +#endif /* CONFIG_MTD_PARTITIONS */
  8619. +
  8620. +static struct flash_platform_data wndr3700_flash_data;
  8621. +
  8622. +static struct gpio_led wndr3700_leds_gpio[] __initdata = {
  8623. + {
  8624. + .name = "wndr3700:green:power",
  8625. + .gpio = WNDR3700_GPIO_LED_POWER_GREEN,
  8626. + .active_low = 1,
  8627. + }, {
  8628. + .name = "wndr3700:orange:power",
  8629. + .gpio = WNDR3700_GPIO_LED_POWER_ORANGE,
  8630. + .active_low = 1,
  8631. + }, {
  8632. + .name = "wndr3700:green:wps",
  8633. + .gpio = WNDR3700_GPIO_LED_WPS_GREEN,
  8634. + .active_low = 1,
  8635. + }, {
  8636. + .name = "wndr3700:orange:wps",
  8637. + .gpio = WNDR3700_GPIO_LED_WPS_ORANGE,
  8638. + .active_low = 1,
  8639. + }, {
  8640. + .name = "wndr3700:green:wan",
  8641. + .gpio = WNDR3700_GPIO_LED_WAN_GREEN,
  8642. + .active_low = 1,
  8643. + }
  8644. +};
  8645. +
  8646. +static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = {
  8647. + {
  8648. + .desc = "reset",
  8649. + .type = EV_KEY,
  8650. + .code = KEY_RESTART,
  8651. + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL,
  8652. + .gpio = WNDR3700_GPIO_BTN_RESET,
  8653. + .active_low = 1,
  8654. + }, {
  8655. + .desc = "wps",
  8656. + .type = EV_KEY,
  8657. + .code = KEY_WPS_BUTTON,
  8658. + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL,
  8659. + .gpio = WNDR3700_GPIO_BTN_WPS,
  8660. + .active_low = 1,
  8661. + }, {
  8662. + .desc = "wifi",
  8663. + .type = EV_KEY,
  8664. + .code = BTN_2,
  8665. + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL,
  8666. + .gpio = WNDR3700_GPIO_BTN_WIFI,
  8667. + .active_low = 1,
  8668. + }
  8669. +};
  8670. +
  8671. +static struct rtl8366_platform_data wndr3700_rtl8366s_data = {
  8672. + .gpio_sda = WNDR3700_GPIO_RTL8366_SDA,
  8673. + .gpio_sck = WNDR3700_GPIO_RTL8366_SCK,
  8674. +};
  8675. +
  8676. +static struct platform_device wndr3700_rtl8366s_device = {
  8677. + .name = RTL8366S_DRIVER_NAME,
  8678. + .id = -1,
  8679. + .dev = {
  8680. + .platform_data = &wndr3700_rtl8366s_data,
  8681. + }
  8682. +};
  8683. +
  8684. +static void __init wndr3700_common_setup(void)
  8685. +{
  8686. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  8687. +
  8688. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr,
  8689. + art + WNDR3700_ETH0_MAC_OFFSET, 0);
  8690. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  8691. + ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  8692. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  8693. + ar71xx_eth0_data.speed = SPEED_1000;
  8694. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  8695. +
  8696. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr,
  8697. + art + WNDR3700_ETH1_MAC_OFFSET, 0);
  8698. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  8699. + ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  8700. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  8701. + ar71xx_eth1_data.phy_mask = 0x10;
  8702. +
  8703. + ar71xx_add_device_eth(0);
  8704. + ar71xx_add_device_eth(1);
  8705. +
  8706. + ar71xx_add_device_usb();
  8707. +
  8708. + ar71xx_add_device_m25p80(&wndr3700_flash_data);
  8709. +
  8710. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio),
  8711. + wndr3700_leds_gpio);
  8712. +
  8713. + ar71xx_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL,
  8714. + ARRAY_SIZE(wndr3700_gpio_keys),
  8715. + wndr3700_gpio_keys);
  8716. +
  8717. + platform_device_register(&wndr3700_rtl8366s_device);
  8718. + platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0);
  8719. +
  8720. + ap94_pci_setup_wmac_led_pin(0, 5);
  8721. + ap94_pci_setup_wmac_led_pin(1, 5);
  8722. +
  8723. + /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */
  8724. + ap94_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6));
  8725. +
  8726. + /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */
  8727. + ap94_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6));
  8728. +
  8729. + ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET,
  8730. + art + WNDR3700_WMAC0_MAC_OFFSET,
  8731. + art + WNDR3700_CALDATA1_OFFSET,
  8732. + art + WNDR3700_WMAC1_MAC_OFFSET);
  8733. +}
  8734. +
  8735. +static void __init wndr3700_setup(void)
  8736. +{
  8737. + wndr3700_flash_data.parts = wndr3700_partitions,
  8738. + wndr3700_flash_data.nr_parts = wndr3700_num_partitions,
  8739. + wndr3700_common_setup();
  8740. +}
  8741. +
  8742. +MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700",
  8743. + wndr3700_setup);
  8744. +
  8745. +static void __init wndr3700v2_setup(void)
  8746. +{
  8747. + wndr3700_flash_data.parts = wndr3700v2_partitions,
  8748. + wndr3700_flash_data.nr_parts = wndr3700v2_num_partitions,
  8749. + wndr3700_common_setup();
  8750. +}
  8751. +
  8752. +MIPS_MACHINE(AR71XX_MACH_WNDR3700V2, "WNDR3700v2", "NETGEAR WNDR3700v2",
  8753. + wndr3700v2_setup);
  8754. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c
  8755. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100
  8756. +++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-08-24 18:17:23.000000000 +0200
  8757. @@ -0,0 +1,150 @@
  8758. +/*
  8759. + * NETGEAR WNR2000 board support
  8760. + *
  8761. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8762. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8763. + * Copyright (C) 2008-2009 Andy Boyett <agb@openwrt.org>
  8764. + *
  8765. + * This program is free software; you can redistribute it and/or modify it
  8766. + * under the terms of the GNU General Public License version 2 as published
  8767. + * by the Free Software Foundation.
  8768. + */
  8769. +
  8770. +#include <linux/mtd/mtd.h>
  8771. +#include <linux/mtd/partitions.h>
  8772. +
  8773. +#include <asm/mach-ar71xx/ar71xx.h>
  8774. +
  8775. +#include "machtype.h"
  8776. +#include "devices.h"
  8777. +#include "dev-m25p80.h"
  8778. +#include "dev-ar9xxx-wmac.h"
  8779. +#include "dev-gpio-buttons.h"
  8780. +#include "dev-leds-gpio.h"
  8781. +
  8782. +#define WNR2000_GPIO_LED_PWR_GREEN 14
  8783. +#define WNR2000_GPIO_LED_PWR_AMBER 7
  8784. +#define WNR2000_GPIO_LED_WPS 4
  8785. +#define WNR2000_GPIO_LED_WLAN 6
  8786. +#define WNR2000_GPIO_BTN_RESET 21
  8787. +#define WNR2000_GPIO_BTN_WPS 8
  8788. +
  8789. +#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */
  8790. +#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL)
  8791. +
  8792. +#ifdef CONFIG_MTD_PARTITIONS
  8793. +static struct mtd_partition wnr2000_partitions[] = {
  8794. + {
  8795. + .name = "u-boot",
  8796. + .offset = 0,
  8797. + .size = 0x040000,
  8798. + .mask_flags = MTD_WRITEABLE,
  8799. + }, {
  8800. + .name = "u-boot-env",
  8801. + .offset = 0x040000,
  8802. + .size = 0x010000,
  8803. + }, {
  8804. + .name = "rootfs",
  8805. + .offset = 0x050000,
  8806. + .size = 0x240000,
  8807. + }, {
  8808. + .name = "user-config",
  8809. + .offset = 0x290000,
  8810. + .size = 0x010000,
  8811. + }, {
  8812. + .name = "uImage",
  8813. + .offset = 0x2a0000,
  8814. + .size = 0x120000,
  8815. + }, {
  8816. + .name = "language_table",
  8817. + .offset = 0x3c0000,
  8818. + .size = 0x020000,
  8819. + }, {
  8820. + .name = "rootfs_checksum",
  8821. + .offset = 0x3e0000,
  8822. + .size = 0x010000,
  8823. + }, {
  8824. + .name = "art",
  8825. + .offset = 0x3f0000,
  8826. + .size = 0x010000,
  8827. + .mask_flags = MTD_WRITEABLE,
  8828. + }
  8829. +};
  8830. +#endif /* CONFIG_MTD_PARTITIONS */
  8831. +
  8832. +static struct flash_platform_data wnr2000_flash_data = {
  8833. +#ifdef CONFIG_MTD_PARTITIONS
  8834. + .parts = wnr2000_partitions,
  8835. + .nr_parts = ARRAY_SIZE(wnr2000_partitions),
  8836. +#endif
  8837. +};
  8838. +
  8839. +static struct gpio_led wnr2000_leds_gpio[] __initdata = {
  8840. + {
  8841. + .name = "wnr2000:green:power",
  8842. + .gpio = WNR2000_GPIO_LED_PWR_GREEN,
  8843. + .active_low = 1,
  8844. + }, {
  8845. + .name = "wnr2000:amber:power",
  8846. + .gpio = WNR2000_GPIO_LED_PWR_AMBER,
  8847. + .active_low = 1,
  8848. + }, {
  8849. + .name = "wnr2000:green:wps",
  8850. + .gpio = WNR2000_GPIO_LED_WPS,
  8851. + .active_low = 1,
  8852. + }, {
  8853. + .name = "wnr2000:blue:wlan",
  8854. + .gpio = WNR2000_GPIO_LED_WLAN,
  8855. + .active_low = 1,
  8856. + }
  8857. +};
  8858. +
  8859. +static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = {
  8860. + {
  8861. + .desc = "reset",
  8862. + .type = EV_KEY,
  8863. + .code = KEY_RESTART,
  8864. + .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL,
  8865. + .gpio = WNR2000_GPIO_BTN_RESET,
  8866. + }, {
  8867. + .desc = "wps",
  8868. + .type = EV_KEY,
  8869. + .code = KEY_WPS_BUTTON,
  8870. + .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL,
  8871. + .gpio = WNR2000_GPIO_BTN_WPS,
  8872. + }
  8873. +};
  8874. +
  8875. +static void __init wnr2000_setup(void)
  8876. +{
  8877. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  8878. +
  8879. + ar71xx_add_device_mdio(0x0);
  8880. +
  8881. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0);
  8882. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8883. + ar71xx_eth0_data.speed = SPEED_100;
  8884. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  8885. + ar71xx_eth0_data.has_ar8216 = 1;
  8886. +
  8887. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1);
  8888. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  8889. + ar71xx_eth1_data.phy_mask = 0x10;
  8890. +
  8891. + ar71xx_add_device_eth(0);
  8892. + ar71xx_add_device_eth(1);
  8893. +
  8894. + ar71xx_add_device_m25p80(&wnr2000_flash_data);
  8895. +
  8896. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio),
  8897. + wnr2000_leds_gpio);
  8898. +
  8899. + ar71xx_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL,
  8900. + ARRAY_SIZE(wnr2000_gpio_keys),
  8901. + wnr2000_gpio_keys);
  8902. +
  8903. +
  8904. + ar9xxx_add_device_wmac(eeprom, NULL);
  8905. +}
  8906. +
  8907. +MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup);
  8908. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c
  8909. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100
  8910. +++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-08-24 18:17:23.000000000 +0200
  8911. @@ -0,0 +1,101 @@
  8912. +/*
  8913. + * Compex WP543/WPJ543 board support
  8914. + *
  8915. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8916. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8917. + *
  8918. + * This program is free software; you can redistribute it and/or modify it
  8919. + * under the terms of the GNU General Public License version 2 as published
  8920. + * by the Free Software Foundation.
  8921. + */
  8922. +
  8923. +#include <linux/mtd/mtd.h>
  8924. +#include <linux/mtd/partitions.h>
  8925. +
  8926. +#include <asm/mach-ar71xx/ar71xx.h>
  8927. +
  8928. +#include "machtype.h"
  8929. +#include "devices.h"
  8930. +#include "dev-m25p80.h"
  8931. +#include "dev-pb42-pci.h"
  8932. +#include "dev-gpio-buttons.h"
  8933. +#include "dev-leds-gpio.h"
  8934. +#include "dev-usb.h"
  8935. +
  8936. +#define WP543_GPIO_SW6 2
  8937. +#define WP543_GPIO_LED_1 3
  8938. +#define WP543_GPIO_LED_2 4
  8939. +#define WP543_GPIO_LED_WLAN 5
  8940. +#define WP543_GPIO_LED_CONN 6
  8941. +#define WP543_GPIO_LED_DIAG 7
  8942. +#define WP543_GPIO_SW4 8
  8943. +
  8944. +#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */
  8945. +#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL)
  8946. +
  8947. +static struct gpio_led wp543_leds_gpio[] __initdata = {
  8948. + {
  8949. + .name = "wp543:green:led1",
  8950. + .gpio = WP543_GPIO_LED_1,
  8951. + .active_low = 1,
  8952. + }, {
  8953. + .name = "wp543:green:led2",
  8954. + .gpio = WP543_GPIO_LED_2,
  8955. + .active_low = 1,
  8956. + }, {
  8957. + .name = "wp543:green:wlan",
  8958. + .gpio = WP543_GPIO_LED_WLAN,
  8959. + .active_low = 1,
  8960. + }, {
  8961. + .name = "wp543:green:conn",
  8962. + .gpio = WP543_GPIO_LED_CONN,
  8963. + .active_low = 1,
  8964. + }, {
  8965. + .name = "wp543:green:diag",
  8966. + .gpio = WP543_GPIO_LED_DIAG,
  8967. + .active_low = 1,
  8968. + }
  8969. +};
  8970. +
  8971. +static struct gpio_keys_button wp543_gpio_keys[] __initdata = {
  8972. + {
  8973. + .desc = "sw6",
  8974. + .type = EV_KEY,
  8975. + .code = BTN_0,
  8976. + .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL,
  8977. + .gpio = WP543_GPIO_SW6,
  8978. + }, {
  8979. + .desc = "sw4",
  8980. + .type = EV_KEY,
  8981. + .code = BTN_1,
  8982. + .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL,
  8983. + .gpio = WP543_GPIO_SW4,
  8984. + }
  8985. +};
  8986. +
  8987. +static void __init wp543_setup(void)
  8988. +{
  8989. + ar71xx_add_device_m25p80(NULL);
  8990. +
  8991. + ar71xx_add_device_mdio(0xfffffff7);
  8992. +
  8993. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0);
  8994. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  8995. + ar71xx_eth0_data.phy_mask = 0x08;
  8996. + ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC |
  8997. + RESET_MODULE_GE0_PHY;
  8998. + ar71xx_add_device_eth(0);
  8999. +
  9000. + ar71xx_add_device_usb();
  9001. +
  9002. + pb42_pci_init();
  9003. +
  9004. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio),
  9005. + wp543_leds_gpio);
  9006. +
  9007. + ar71xx_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL,
  9008. + ARRAY_SIZE(wp543_gpio_keys),
  9009. + wp543_gpio_keys);
  9010. +}
  9011. +
  9012. +MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup);
  9013. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c
  9014. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100
  9015. +++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-08-24 18:17:23.000000000 +0200
  9016. @@ -0,0 +1,161 @@
  9017. +/*
  9018. + * Linksys WRT160NL board support
  9019. + *
  9020. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  9021. + *
  9022. + * This program is free software; you can redistribute it and/or modify it
  9023. + * under the terms of the GNU General Public License version 2 as published
  9024. + * by the Free Software Foundation.
  9025. + */
  9026. +
  9027. +#include <linux/mtd/mtd.h>
  9028. +#include <linux/mtd/partitions.h>
  9029. +
  9030. +#include <asm/mach-ar71xx/ar71xx.h>
  9031. +
  9032. +#include "machtype.h"
  9033. +#include "devices.h"
  9034. +#include "dev-m25p80.h"
  9035. +#include "dev-ar9xxx-wmac.h"
  9036. +#include "dev-gpio-buttons.h"
  9037. +#include "dev-leds-gpio.h"
  9038. +#include "dev-usb.h"
  9039. +#include "nvram.h"
  9040. +
  9041. +#define WRT160NL_GPIO_LED_POWER 14
  9042. +#define WRT160NL_GPIO_LED_WPS_AMBER 9
  9043. +#define WRT160NL_GPIO_LED_WPS_BLUE 8
  9044. +#define WRT160NL_GPIO_LED_WLAN 6
  9045. +
  9046. +#define WRT160NL_GPIO_BTN_WPS 7
  9047. +#define WRT160NL_GPIO_BTN_RESET 21
  9048. +
  9049. +#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */
  9050. +#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL)
  9051. +
  9052. +#define WRT160NL_NVRAM_ADDR 0x1f7e0000
  9053. +#define WRT160NL_NVRAM_SIZE 0x10000
  9054. +
  9055. +#ifdef CONFIG_MTD_PARTITIONS
  9056. +static struct mtd_partition wrt160nl_partitions[] = {
  9057. + {
  9058. + .name = "u-boot",
  9059. + .offset = 0,
  9060. + .size = 0x040000,
  9061. + .mask_flags = MTD_WRITEABLE,
  9062. + }, {
  9063. + .name = "kernel",
  9064. + .offset = 0x040000,
  9065. + .size = 0x0e0000,
  9066. + }, {
  9067. + .name = "filesytem",
  9068. + .offset = 0x120000,
  9069. + .size = 0x6c0000,
  9070. + }, {
  9071. + .name = "nvram",
  9072. + .offset = 0x7e0000,
  9073. + .size = 0x010000,
  9074. + .mask_flags = MTD_WRITEABLE,
  9075. + }, {
  9076. + .name = "ART",
  9077. + .offset = 0x7f0000,
  9078. + .size = 0x010000,
  9079. + .mask_flags = MTD_WRITEABLE,
  9080. + }, {
  9081. + .name = "firmware",
  9082. + .offset = 0x040000,
  9083. + .size = 0x7a0000,
  9084. + }
  9085. +};
  9086. +#endif /* CONFIG_MTD_PARTITIONS */
  9087. +
  9088. +static struct flash_platform_data wrt160nl_flash_data = {
  9089. +#ifdef CONFIG_MTD_PARTITIONS
  9090. + .parts = wrt160nl_partitions,
  9091. + .nr_parts = ARRAY_SIZE(wrt160nl_partitions),
  9092. +#endif
  9093. +};
  9094. +
  9095. +static struct gpio_led wrt160nl_leds_gpio[] __initdata = {
  9096. + {
  9097. + .name = "wrt160nl:blue:power",
  9098. + .gpio = WRT160NL_GPIO_LED_POWER,
  9099. + .active_low = 1,
  9100. + .default_trigger = "default-on",
  9101. + }, {
  9102. + .name = "wrt160nl:amber:wps",
  9103. + .gpio = WRT160NL_GPIO_LED_WPS_AMBER,
  9104. + .active_low = 1,
  9105. + }, {
  9106. + .name = "wrt160nl:blue:wps",
  9107. + .gpio = WRT160NL_GPIO_LED_WPS_BLUE,
  9108. + .active_low = 1,
  9109. + }, {
  9110. + .name = "wrt160nl:blue:wlan",
  9111. + .gpio = WRT160NL_GPIO_LED_WLAN,
  9112. + .active_low = 1,
  9113. + }
  9114. +};
  9115. +
  9116. +static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = {
  9117. + {
  9118. + .desc = "reset",
  9119. + .type = EV_KEY,
  9120. + .code = KEY_RESTART,
  9121. + .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL,
  9122. + .gpio = WRT160NL_GPIO_BTN_RESET,
  9123. + .active_low = 1,
  9124. + }, {
  9125. + .desc = "wps",
  9126. + .type = EV_KEY,
  9127. + .code = KEY_WPS_BUTTON,
  9128. + .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL,
  9129. + .gpio = WRT160NL_GPIO_BTN_WPS,
  9130. + .active_low = 1,
  9131. + }
  9132. +};
  9133. +
  9134. +static void __init wrt160nl_setup(void)
  9135. +{
  9136. + const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR);
  9137. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  9138. + u8 mac[6];
  9139. +
  9140. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  9141. + "lan_hwaddr=", mac) == 0) {
  9142. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  9143. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  9144. + }
  9145. +
  9146. + ar71xx_add_device_mdio(0x0);
  9147. +
  9148. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  9149. + ar71xx_eth0_data.phy_mask = 0x01;
  9150. +
  9151. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  9152. + ar71xx_eth1_data.phy_mask = 0x10;
  9153. +
  9154. + ar71xx_add_device_eth(0);
  9155. + ar71xx_add_device_eth(1);
  9156. +
  9157. + ar71xx_add_device_m25p80(&wrt160nl_flash_data);
  9158. +
  9159. + ar71xx_add_device_usb();
  9160. +
  9161. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  9162. + "wl0_hwaddr=", mac) == 0)
  9163. + ar9xxx_add_device_wmac(eeprom, mac);
  9164. + else
  9165. + ar9xxx_add_device_wmac(eeprom, NULL);
  9166. +
  9167. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio),
  9168. + wrt160nl_leds_gpio);
  9169. +
  9170. + ar71xx_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL,
  9171. + ARRAY_SIZE(wrt160nl_gpio_keys),
  9172. + wrt160nl_gpio_keys);
  9173. +
  9174. +}
  9175. +
  9176. +MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL",
  9177. + wrt160nl_setup);
  9178. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c
  9179. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100
  9180. +++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-08-24 18:17:23.000000000 +0200
  9181. @@ -0,0 +1,164 @@
  9182. +/*
  9183. + * Linksys WRT400N board support
  9184. + *
  9185. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  9186. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  9187. + *
  9188. + * This program is free software; you can redistribute it and/or modify it
  9189. + * under the terms of the GNU General Public License version 2 as published
  9190. + * by the Free Software Foundation.
  9191. + */
  9192. +
  9193. +#include <linux/mtd/mtd.h>
  9194. +#include <linux/mtd/partitions.h>
  9195. +
  9196. +#include <asm/mach-ar71xx/ar71xx.h>
  9197. +
  9198. +#include "machtype.h"
  9199. +#include "devices.h"
  9200. +#include "dev-ap94-pci.h"
  9201. +#include "dev-m25p80.h"
  9202. +#include "dev-gpio-buttons.h"
  9203. +#include "dev-leds-gpio.h"
  9204. +
  9205. +#define WRT400N_GPIO_LED_ORANGE 5
  9206. +#define WRT400N_GPIO_LED_GREEN 4
  9207. +#define WRT400N_GPIO_LED_POWER 1
  9208. +#define WRT400N_GPIO_LED_WLAN 0
  9209. +
  9210. +#define WRT400N_GPIO_BTN_RESET 8
  9211. +#define WRT400N_GPIO_BTN_WLSEC 3
  9212. +
  9213. +#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */
  9214. +#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL)
  9215. +
  9216. +#define WRT400N_MAC_ADDR_OFFSET 0x120c
  9217. +#define WRT400N_CALDATA0_OFFSET 0x1000
  9218. +#define WRT400N_CALDATA1_OFFSET 0x5000
  9219. +
  9220. +#ifdef CONFIG_MTD_PARTITIONS
  9221. +static struct mtd_partition wrt400n_partitions[] = {
  9222. + {
  9223. + .name = "uboot",
  9224. + .offset = 0,
  9225. + .size = 0x030000,
  9226. + .mask_flags = MTD_WRITEABLE,
  9227. + }, {
  9228. + .name = "env",
  9229. + .offset = 0x030000,
  9230. + .size = 0x010000,
  9231. + .mask_flags = MTD_WRITEABLE,
  9232. + }, {
  9233. + .name = "linux",
  9234. + .offset = 0x040000,
  9235. + .size = 0x140000,
  9236. + }, {
  9237. + .name = "rootfs",
  9238. + .offset = 0x180000,
  9239. + .size = 0x630000,
  9240. + }, {
  9241. + .name = "nvram",
  9242. + .offset = 0x7b0000,
  9243. + .size = 0x010000,
  9244. + .mask_flags = MTD_WRITEABLE,
  9245. + }, {
  9246. + .name = "factory",
  9247. + .offset = 0x7c0000,
  9248. + .size = 0x010000,
  9249. + .mask_flags = MTD_WRITEABLE,
  9250. + }, {
  9251. + .name = "language",
  9252. + .offset = 0x7d0000,
  9253. + .size = 0x020000,
  9254. + .mask_flags = MTD_WRITEABLE,
  9255. + }, {
  9256. + .name = "caldata",
  9257. + .offset = 0x7f0000,
  9258. + .size = 0x010000,
  9259. + .mask_flags = MTD_WRITEABLE,
  9260. + }, {
  9261. + .name = "firmware",
  9262. + .offset = 0x040000,
  9263. + .size = 0x770000,
  9264. + }
  9265. +};
  9266. +#endif /* CONFIG_MTD_PARTITIONS */
  9267. +
  9268. +static struct flash_platform_data wrt400n_flash_data = {
  9269. +#ifdef CONFIG_MTD_PARTITIONS
  9270. + .parts = wrt400n_partitions,
  9271. + .nr_parts = ARRAY_SIZE(wrt400n_partitions),
  9272. +#endif
  9273. +};
  9274. +
  9275. +static struct gpio_led wrt400n_leds_gpio[] __initdata = {
  9276. + {
  9277. + .name = "wrt400n:green:status",
  9278. + .gpio = WRT400N_GPIO_LED_GREEN,
  9279. + .active_low = 1,
  9280. + }, {
  9281. + .name = "wrt400n:amber:aoss",
  9282. + .gpio = WRT400N_GPIO_LED_ORANGE,
  9283. + .active_low = 1,
  9284. + }, {
  9285. + .name = "wrt400n:green:wlan",
  9286. + .gpio = WRT400N_GPIO_LED_WLAN,
  9287. + .active_low = 1,
  9288. + }, {
  9289. + .name = "wrt400n:green:power",
  9290. + .gpio = WRT400N_GPIO_LED_POWER,
  9291. + .active_low = 1,
  9292. + }
  9293. +};
  9294. +
  9295. +static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = {
  9296. + {
  9297. + .desc = "reset",
  9298. + .type = EV_KEY,
  9299. + .code = KEY_RESTART,
  9300. + .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL,
  9301. + .gpio = WRT400N_GPIO_BTN_RESET,
  9302. + .active_low = 1,
  9303. + }, {
  9304. + .desc = "wlsec",
  9305. + .type = EV_KEY,
  9306. + .code = KEY_WPS_BUTTON,
  9307. + .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL,
  9308. + .gpio = WRT400N_GPIO_BTN_WLSEC,
  9309. + .active_low = 1,
  9310. + }
  9311. +};
  9312. +
  9313. +static void __init wrt400n_setup(void)
  9314. +{
  9315. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  9316. + u8 *mac = art + WRT400N_MAC_ADDR_OFFSET;
  9317. +
  9318. + ar71xx_add_device_mdio(0x0);
  9319. +
  9320. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1);
  9321. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  9322. + ar71xx_eth0_data.speed = SPEED_100;
  9323. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  9324. +
  9325. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2);
  9326. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  9327. + ar71xx_eth1_data.phy_mask = 0x10;
  9328. +
  9329. + ar71xx_add_device_eth(0);
  9330. + ar71xx_add_device_eth(1);
  9331. +
  9332. + ar71xx_add_device_m25p80(&wrt400n_flash_data);
  9333. +
  9334. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio),
  9335. + wrt400n_leds_gpio);
  9336. +
  9337. + ar71xx_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL,
  9338. + ARRAY_SIZE(wrt400n_gpio_keys),
  9339. + wrt400n_gpio_keys);
  9340. +
  9341. + ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL,
  9342. + art + WRT400N_CALDATA1_OFFSET, NULL);
  9343. +}
  9344. +
  9345. +MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup);
  9346. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c
  9347. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 1970-01-01 01:00:00.000000000 +0100
  9348. +++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 2011-08-24 18:17:23.000000000 +0200
  9349. @@ -0,0 +1,231 @@
  9350. +/*
  9351. + * Buffalo WZR-HP-AG300H board support
  9352. + *
  9353. + * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
  9354. + *
  9355. + * This program is free software; you can redistribute it and/or modify it
  9356. + * under the terms of the GNU General Public License version 2 as published
  9357. + * by the Free Software Foundation.
  9358. + */
  9359. +
  9360. +#include <linux/platform_device.h>
  9361. +#include <linux/mtd/mtd.h>
  9362. +#include <linux/mtd/partitions.h>
  9363. +#include <linux/mtd/concat.h>
  9364. +
  9365. +#include <asm/mips_machine.h>
  9366. +#include <asm/mach-ar71xx/ar71xx.h>
  9367. +#include <asm/mach-ar71xx/gpio.h>
  9368. +
  9369. +#include "machtype.h"
  9370. +#include "devices.h"
  9371. +#include "dev-ap94-pci.h"
  9372. +#include "dev-gpio-buttons.h"
  9373. +#include "dev-leds-gpio.h"
  9374. +#include "dev-m25p80.h"
  9375. +#include "dev-usb.h"
  9376. +
  9377. +#define WZRHPAG300H_MAC_OFFSET 0x20c
  9378. +#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */
  9379. +#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL)
  9380. +
  9381. +#ifdef CONFIG_MTD_PARTITIONS
  9382. +static struct mtd_partition wzrhpag300h_flash_partitions[] = {
  9383. + {
  9384. + .name = "u-boot",
  9385. + .offset = 0,
  9386. + .size = 0x0040000,
  9387. + .mask_flags = MTD_WRITEABLE,
  9388. + }, {
  9389. + .name = "u-boot-env",
  9390. + .offset = 0x0040000,
  9391. + .size = 0x0010000,
  9392. + .mask_flags = MTD_WRITEABLE,
  9393. + }, {
  9394. + .name = "art",
  9395. + .offset = 0x0050000,
  9396. + .size = 0x0010000,
  9397. + .mask_flags = MTD_WRITEABLE,
  9398. + }, {
  9399. + .name = "kernel",
  9400. + .offset = 0x0060000,
  9401. + .size = 0x0100000,
  9402. + }, {
  9403. + .name = "rootfs",
  9404. + .offset = 0x0160000,
  9405. + .size = 0x1e90000,
  9406. + }, {
  9407. + .name = "user_property",
  9408. + .offset = 0x1ff0000,
  9409. + .size = 0x0010000,
  9410. + .mask_flags = MTD_WRITEABLE,
  9411. + }, {
  9412. + .name = "firmware",
  9413. + .offset = 0x0060000,
  9414. + .size = 0x1f90000,
  9415. + }
  9416. +};
  9417. +
  9418. +#endif /* CONFIG_MTD_PARTITIONS */
  9419. +
  9420. +static struct mtd_info *concat_devs[2] = { NULL, NULL };
  9421. +static struct work_struct mtd_concat_work;
  9422. +
  9423. +static void mtd_concat_add_work(struct work_struct *work)
  9424. +{
  9425. + struct mtd_info *mtd;
  9426. +
  9427. + mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash");
  9428. +
  9429. +#ifdef CONFIG_MTD_PARTITIONS
  9430. + add_mtd_partitions(mtd, wzrhpag300h_flash_partitions,
  9431. + ARRAY_SIZE(wzrhpag300h_flash_partitions));
  9432. +#else
  9433. + add_mtd_device(mtd);
  9434. +#endif
  9435. +}
  9436. +
  9437. +static void mtd_concat_add(struct mtd_info *mtd)
  9438. +{
  9439. + static bool registered = false;
  9440. +
  9441. + if (registered)
  9442. + return;
  9443. +
  9444. + if (!strcmp(mtd->name, "spi0.0"))
  9445. + concat_devs[0] = mtd;
  9446. + else if (!strcmp(mtd->name, "spi0.1"))
  9447. + concat_devs[1] = mtd;
  9448. + else
  9449. + return;
  9450. +
  9451. + if (!concat_devs[0] || !concat_devs[1])
  9452. + return;
  9453. +
  9454. + registered = true;
  9455. + INIT_WORK(&mtd_concat_work, mtd_concat_add_work);
  9456. + schedule_work(&mtd_concat_work);
  9457. +}
  9458. +
  9459. +static void mtd_concat_remove(struct mtd_info *mtd)
  9460. +{
  9461. +}
  9462. +
  9463. +static void add_mtd_concat_notifier(void)
  9464. +{
  9465. + static struct mtd_notifier not = {
  9466. + .add = mtd_concat_add,
  9467. + .remove = mtd_concat_remove,
  9468. + };
  9469. +
  9470. + register_mtd_user(&not);
  9471. +}
  9472. +
  9473. +static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = {
  9474. + {
  9475. + .name = "wzr-hp-ag300h:red:diag",
  9476. + .gpio = 1,
  9477. + .active_low = 1,
  9478. + },
  9479. +};
  9480. +
  9481. +
  9482. +static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = {
  9483. + {
  9484. + .desc = "reset",
  9485. + .type = EV_KEY,
  9486. + .code = KEY_RESTART,
  9487. + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL,
  9488. + .gpio = 11,
  9489. + .active_low = 1,
  9490. + }, {
  9491. + .desc = "usb",
  9492. + .type = EV_KEY,
  9493. + .code = BTN_2,
  9494. + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL,
  9495. + .gpio = 3,
  9496. + .active_low = 1,
  9497. + }, {
  9498. + .desc = "aoss",
  9499. + .type = EV_KEY,
  9500. + .code = KEY_WPS_BUTTON,
  9501. + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL,
  9502. + .gpio = 5,
  9503. + .active_low = 1,
  9504. + }, {
  9505. + .desc = "router_auto",
  9506. + .type = EV_KEY,
  9507. + .code = BTN_6,
  9508. + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL,
  9509. + .gpio = 6,
  9510. + .active_low = 1,
  9511. + }, {
  9512. + .desc = "router_off",
  9513. + .type = EV_KEY,
  9514. + .code = BTN_5,
  9515. + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL,
  9516. + .gpio = 7,
  9517. + .active_low = 1,
  9518. + }
  9519. +};
  9520. +
  9521. +static struct spi_board_info ar71xx_spi_info[] = {
  9522. + {
  9523. + .bus_num = 0,
  9524. + .chip_select = 0,
  9525. + .max_speed_hz = 25000000,
  9526. + .modalias = "m25p80",
  9527. + },
  9528. + {
  9529. + .bus_num = 0,
  9530. + .chip_select = 1,
  9531. + .max_speed_hz = 25000000,
  9532. + .modalias = "m25p80",
  9533. + }
  9534. +};
  9535. +
  9536. +static void __init wzrhpag300h_setup(void)
  9537. +{
  9538. + u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000);
  9539. + u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000);
  9540. + u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET;
  9541. + u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET;
  9542. +
  9543. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0);
  9544. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 1);
  9545. +
  9546. + ar71xx_add_device_mdio(~(BIT(0) | BIT(4)));
  9547. +
  9548. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  9549. + ar71xx_eth0_data.speed = SPEED_1000;
  9550. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  9551. + ar71xx_eth0_data.phy_mask = BIT(0);
  9552. +
  9553. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  9554. + ar71xx_eth1_data.phy_mask = BIT(4);
  9555. +
  9556. + ar71xx_add_device_eth(0);
  9557. + ar71xx_add_device_eth(1);
  9558. +
  9559. + ar71xx_add_device_usb();
  9560. + gpio_request(2, "usb");
  9561. + gpio_direction_output(2, 1);
  9562. +
  9563. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio),
  9564. + wzrhpag300h_leds_gpio);
  9565. +
  9566. + ar71xx_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL,
  9567. + ARRAY_SIZE(wzrhpag300h_gpio_keys),
  9568. + wzrhpag300h_gpio_keys);
  9569. +
  9570. + ar71xx_add_device_spi(NULL, ar71xx_spi_info,
  9571. + ARRAY_SIZE(ar71xx_spi_info));
  9572. +
  9573. + add_mtd_concat_notifier();
  9574. +
  9575. + ap94_pci_init(eeprom1, mac1, eeprom2, mac2);
  9576. +}
  9577. +
  9578. +MIPS_MACHINE(AR71XX_MACH_WZR_HP_AG300H, "WZR-HP-AG300H",
  9579. + "Buffalo WZR-HP-AG300H", wzrhpag300h_setup);
  9580. +
  9581. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c
  9582. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100
  9583. +++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-08-24 18:17:23.000000000 +0200
  9584. @@ -0,0 +1,292 @@
  9585. +/*
  9586. + * Buffalo WZR-HP-G300NH board support
  9587. + *
  9588. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  9589. + *
  9590. + * This program is free software; you can redistribute it and/or modify it
  9591. + * under the terms of the GNU General Public License version 2 as published
  9592. + * by the Free Software Foundation.
  9593. + */
  9594. +
  9595. +#include <linux/platform_device.h>
  9596. +#include <linux/mtd/mtd.h>
  9597. +#include <linux/mtd/partitions.h>
  9598. +#include <linux/nxp_74hc153.h>
  9599. +#include <linux/rtl8366.h>
  9600. +
  9601. +#include <asm/mips_machine.h>
  9602. +#include <asm/mach-ar71xx/ar71xx.h>
  9603. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  9604. +
  9605. +#include "machtype.h"
  9606. +#include "devices.h"
  9607. +#include "dev-ar9xxx-wmac.h"
  9608. +#include "dev-gpio-buttons.h"
  9609. +#include "dev-leds-gpio.h"
  9610. +#include "dev-usb.h"
  9611. +
  9612. +#define WZRHPG300NH_GPIO_LED_USB 0
  9613. +#define WZRHPG300NH_GPIO_LED_DIAG 1
  9614. +#define WZRHPG300NH_GPIO_LED_WIRELESS 6
  9615. +#define WZRHPG300NH_GPIO_LED_SECURITY 17
  9616. +#define WZRHPG300NH_GPIO_LED_ROUTER 18
  9617. +
  9618. +#define WZRHPG300NH_GPIO_RTL8366_SDA 19
  9619. +#define WZRHPG300NH_GPIO_RTL8366_SCK 20
  9620. +
  9621. +#define WZRHPG300NH_GPIO_74HC153_S0 9
  9622. +#define WZRHPG300NH_GPIO_74HC153_S1 11
  9623. +#define WZRHPG300NH_GPIO_74HC153_1Y 12
  9624. +#define WZRHPG300NH_GPIO_74HC153_2Y 14
  9625. +
  9626. +#define WZRHPG300NH_GPIO_EXP_BASE 32
  9627. +#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0)
  9628. +#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1)
  9629. +#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2)
  9630. +#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3)
  9631. +#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5)
  9632. +#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6)
  9633. +#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7)
  9634. +
  9635. +#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */
  9636. +#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL)
  9637. +
  9638. +#define WZRHPG300NH_MAC_OFFSET 0x20c
  9639. +
  9640. +#ifdef CONFIG_MTD_PARTITIONS
  9641. +static struct mtd_partition wzrhpg300nh_flash_partitions[] = {
  9642. + {
  9643. + .name = "u-boot",
  9644. + .offset = 0,
  9645. + .size = 0x0040000,
  9646. + .mask_flags = MTD_WRITEABLE,
  9647. + }, {
  9648. + .name = "u-boot-env",
  9649. + .offset = 0x0040000,
  9650. + .size = 0x0020000,
  9651. + .mask_flags = MTD_WRITEABLE,
  9652. + }, {
  9653. + .name = "kernel",
  9654. + .offset = 0x0060000,
  9655. + .size = 0x0100000,
  9656. + }, {
  9657. + .name = "rootfs",
  9658. + .offset = 0x0160000,
  9659. + .size = 0x1e60000,
  9660. + }, {
  9661. + .name = "user_property",
  9662. + .offset = 0x1fc0000,
  9663. + .size = 0x0020000,
  9664. + .mask_flags = MTD_WRITEABLE,
  9665. + }, {
  9666. + .name = "art",
  9667. + .offset = 0x1fe0000,
  9668. + .size = 0x0020000,
  9669. + .mask_flags = MTD_WRITEABLE,
  9670. + }, {
  9671. + .name = "firmware",
  9672. + .offset = 0x0060000,
  9673. + .size = 0x1f60000,
  9674. + }
  9675. +};
  9676. +#endif /* CONFIG_MTD_PARTITIONS */
  9677. +
  9678. +static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = {
  9679. + .width = 2,
  9680. +#ifdef CONFIG_MTD_PARTITIONS
  9681. + .parts = wzrhpg300nh_flash_partitions,
  9682. + .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions),
  9683. +#endif
  9684. +};
  9685. +
  9686. +#define WZRHPG300NH_FLASH_BASE 0x1e000000
  9687. +#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024)
  9688. +
  9689. +static struct resource wzrhpg300nh_flash_resources[] = {
  9690. + [0] = {
  9691. + .start = WZRHPG300NH_FLASH_BASE,
  9692. + .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1,
  9693. + .flags = IORESOURCE_MEM,
  9694. + },
  9695. +};
  9696. +
  9697. +static struct platform_device wzrhpg300nh_flash_device = {
  9698. + .name = "ar91xx-flash",
  9699. + .id = -1,
  9700. + .resource = wzrhpg300nh_flash_resources,
  9701. + .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources),
  9702. + .dev = {
  9703. + .platform_data = &wzrhpg300nh_flash_data,
  9704. + }
  9705. +};
  9706. +
  9707. +static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = {
  9708. + {
  9709. + .name = "wzr-hp-g300nh:orange:security",
  9710. + .gpio = WZRHPG300NH_GPIO_LED_SECURITY,
  9711. + .active_low = 1,
  9712. + }, {
  9713. + .name = "wzr-hp-g300nh:green:wireless",
  9714. + .gpio = WZRHPG300NH_GPIO_LED_WIRELESS,
  9715. + .active_low = 1,
  9716. + }, {
  9717. + .name = "wzr-hp-g300nh:green:router",
  9718. + .gpio = WZRHPG300NH_GPIO_LED_ROUTER,
  9719. + .active_low = 1,
  9720. + }, {
  9721. + .name = "wzr-hp-g300nh:red:diag",
  9722. + .gpio = WZRHPG300NH_GPIO_LED_DIAG,
  9723. + .active_low = 1,
  9724. + }, {
  9725. + .name = "wzr-hp-g300nh:blue:usb",
  9726. + .gpio = WZRHPG300NH_GPIO_LED_USB,
  9727. + .active_low = 1,
  9728. + }
  9729. +};
  9730. +
  9731. +static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = {
  9732. + {
  9733. + .desc = "reset",
  9734. + .type = EV_KEY,
  9735. + .code = KEY_RESTART,
  9736. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9737. + .gpio = WZRHPG300NH_GPIO_BTN_RESET,
  9738. + .active_low = 1,
  9739. + }, {
  9740. + .desc = "aoss",
  9741. + .type = EV_KEY,
  9742. + .code = KEY_WPS_BUTTON,
  9743. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9744. + .gpio = WZRHPG300NH_GPIO_BTN_AOSS,
  9745. + .active_low = 1,
  9746. + }, {
  9747. + .desc = "usb",
  9748. + .type = EV_KEY,
  9749. + .code = BTN_2,
  9750. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9751. + .gpio = WZRHPG300NH_GPIO_BTN_USB,
  9752. + .active_low = 1,
  9753. + }, {
  9754. + .desc = "qos_on",
  9755. + .type = EV_KEY,
  9756. + .code = BTN_3,
  9757. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9758. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON,
  9759. + .active_low = 0,
  9760. + }, {
  9761. + .desc = "qos_off",
  9762. + .type = EV_KEY,
  9763. + .code = BTN_4,
  9764. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9765. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF,
  9766. + .active_low = 0,
  9767. + }, {
  9768. + .desc = "router_on",
  9769. + .type = EV_KEY,
  9770. + .code = BTN_5,
  9771. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9772. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON,
  9773. + .active_low = 0,
  9774. + }, {
  9775. + .desc = "router_auto",
  9776. + .type = EV_KEY,
  9777. + .code = BTN_6,
  9778. + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL,
  9779. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO,
  9780. + .active_low = 0,
  9781. + }
  9782. +};
  9783. +
  9784. +static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = {
  9785. + .gpio_base = WZRHPG300NH_GPIO_EXP_BASE,
  9786. + .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0,
  9787. + .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1,
  9788. + .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y,
  9789. + .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y,
  9790. +};
  9791. +
  9792. +static struct platform_device wzrhpg300nh_74hc153_device = {
  9793. + .name = NXP_74HC153_DRIVER_NAME,
  9794. + .id = -1,
  9795. + .dev = {
  9796. + .platform_data = &wzrhpg300nh_74hc153_data,
  9797. + }
  9798. +};
  9799. +
  9800. +static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = {
  9801. + .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA,
  9802. + .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK,
  9803. +};
  9804. +
  9805. +static struct platform_device wzrhpg300nh_rtl8366s_device = {
  9806. + .name = RTL8366S_DRIVER_NAME,
  9807. + .id = -1,
  9808. + .dev = {
  9809. + .platform_data = &wzrhpg300nh_rtl8366_data,
  9810. + }
  9811. +};
  9812. +
  9813. +static struct platform_device wzrhpg300nh_rtl8366rb_device = {
  9814. + .name = RTL8366RB_DRIVER_NAME,
  9815. + .id = -1,
  9816. + .dev = {
  9817. + .platform_data = &wzrhpg300nh_rtl8366_data,
  9818. + }
  9819. +};
  9820. +
  9821. +static void __init wzrhpg300nh_setup(void)
  9822. +{
  9823. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  9824. + u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET;
  9825. + bool hasrtl8366rb = false;
  9826. +
  9827. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  9828. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  9829. +
  9830. + if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB)
  9831. + hasrtl8366rb = true;
  9832. +
  9833. + if (hasrtl8366rb) {
  9834. + ar71xx_eth0_pll_data.pll_1000 = 0x1f000000;
  9835. + ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev;
  9836. + ar71xx_eth1_pll_data.pll_1000 = 0x100;
  9837. + ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev;
  9838. + } else {
  9839. + ar71xx_eth0_pll_data.pll_1000 = 0x1e000100;
  9840. + ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  9841. + ar71xx_eth1_pll_data.pll_1000 = 0x1e000100;
  9842. + ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  9843. + }
  9844. +
  9845. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  9846. + ar71xx_eth0_data.speed = SPEED_1000;
  9847. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  9848. +
  9849. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  9850. + ar71xx_eth1_data.phy_mask = 0x10;
  9851. +
  9852. + ar71xx_add_device_eth(0);
  9853. + ar71xx_add_device_eth(1);
  9854. +
  9855. + ar71xx_add_device_usb();
  9856. + ar9xxx_add_device_wmac(eeprom, NULL);
  9857. +
  9858. + platform_device_register(&wzrhpg300nh_74hc153_device);
  9859. + platform_device_register(&wzrhpg300nh_flash_device);
  9860. +
  9861. + if (hasrtl8366rb)
  9862. + platform_device_register(&wzrhpg300nh_rtl8366rb_device);
  9863. + else
  9864. + platform_device_register(&wzrhpg300nh_rtl8366s_device);
  9865. +
  9866. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio),
  9867. + wzrhpg300nh_leds_gpio);
  9868. +
  9869. + ar71xx_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL,
  9870. + ARRAY_SIZE(wzrhpg300nh_gpio_keys),
  9871. + wzrhpg300nh_gpio_keys);
  9872. +
  9873. +}
  9874. +
  9875. +MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH",
  9876. + "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup);
  9877. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c
  9878. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c 1970-01-01 01:00:00.000000000 +0100
  9879. +++ linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c 2011-08-24 18:17:23.000000000 +0200
  9880. @@ -0,0 +1,214 @@
  9881. +/*
  9882. + * Zcomax ZCN-1523H-2-8/5-16 board support
  9883. + *
  9884. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  9885. + *
  9886. + * This program is free software; you can redistribute it and/or modify it
  9887. + * under the terms of the GNU General Public License version 2 as published
  9888. + * by the Free Software Foundation.
  9889. + */
  9890. +
  9891. +#include <linux/mtd/mtd.h>
  9892. +#include <linux/mtd/partitions.h>
  9893. +
  9894. +#include <asm/mach-ar71xx/ar71xx.h>
  9895. +
  9896. +#include "machtype.h"
  9897. +#include "devices.h"
  9898. +#include "dev-m25p80.h"
  9899. +#include "dev-ap91-pci.h"
  9900. +#include "dev-gpio-buttons.h"
  9901. +#include "dev-leds-gpio.h"
  9902. +
  9903. +#define ZCN_1523H_GPIO_BTN_RESET 0
  9904. +#define ZCN_1523H_GPIO_LED_INIT 11
  9905. +#define ZCN_1523H_GPIO_LED_LAN1 17
  9906. +
  9907. +#define ZCN_1523H_2_GPIO_LED_WEAK 13
  9908. +#define ZCN_1523H_2_GPIO_LED_MEDIUM 14
  9909. +#define ZCN_1523H_2_GPIO_LED_STRONG 15
  9910. +
  9911. +#define ZCN_1523H_5_GPIO_LED_UNKNOWN 1
  9912. +#define ZCN_1523H_5_GPIO_LED_LAN2 13
  9913. +#define ZCN_1523H_5_GPIO_LED_WEAK 14
  9914. +#define ZCN_1523H_5_GPIO_LED_MEDIUM 15
  9915. +#define ZCN_1523H_5_GPIO_LED_STRONG 16
  9916. +
  9917. +#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */
  9918. +#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL)
  9919. +
  9920. +#ifdef CONFIG_MTD_PARTITIONS
  9921. +static struct mtd_partition zcn_1523h_partitions[] = {
  9922. + {
  9923. + .name = "u-boot",
  9924. + .offset = 0,
  9925. + .size = 0x040000,
  9926. + .mask_flags = MTD_WRITEABLE,
  9927. + }, {
  9928. + .name = "u-boot-env",
  9929. + .offset = 0x040000,
  9930. + .size = 0x010000,
  9931. + .mask_flags = MTD_WRITEABLE,
  9932. + }, {
  9933. + .name = "rootfs",
  9934. + .offset = 0x050000,
  9935. + .size = 0x610000,
  9936. + }, {
  9937. + .name = "kernel",
  9938. + .offset = 0x660000,
  9939. + .size = 0x170000,
  9940. + }, {
  9941. + .name = "configure",
  9942. + .offset = 0x7d0000,
  9943. + .size = 0x010000,
  9944. + .mask_flags = MTD_WRITEABLE,
  9945. + }, {
  9946. + .name = "mfg",
  9947. + .offset = 0x7e0000,
  9948. + .size = 0x010000,
  9949. + .mask_flags = MTD_WRITEABLE,
  9950. + }, {
  9951. + .name = "eeprom",
  9952. + .offset = 0x7f0000,
  9953. + .size = 0x010000,
  9954. + .mask_flags = MTD_WRITEABLE,
  9955. + }, {
  9956. + .name = "firmware",
  9957. + .offset = 0x050000,
  9958. + .size = 0x780000,
  9959. + }
  9960. +};
  9961. +#endif /* CONFIG_MTD_PARTITIONS */
  9962. +
  9963. +static struct flash_platform_data zcn_1523h_flash_data = {
  9964. +#ifdef CONFIG_MTD_PARTITIONS
  9965. + .parts = zcn_1523h_partitions,
  9966. + .nr_parts = ARRAY_SIZE(zcn_1523h_partitions),
  9967. +#endif
  9968. +};
  9969. +
  9970. +static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = {
  9971. + {
  9972. + .desc = "reset",
  9973. + .type = EV_KEY,
  9974. + .code = KEY_RESTART,
  9975. + .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL,
  9976. + .gpio = ZCN_1523H_GPIO_BTN_RESET,
  9977. + .active_low = 1,
  9978. + }
  9979. +};
  9980. +
  9981. +static struct gpio_led zcn_1523h_leds_gpio[] __initdata = {
  9982. + {
  9983. + .name = "zcn-1523h:amber:init",
  9984. + .gpio = ZCN_1523H_GPIO_LED_INIT,
  9985. + .active_low = 1,
  9986. + }, {
  9987. + .name = "zcn-1523h:green:lan1",
  9988. + .gpio = ZCN_1523H_GPIO_LED_LAN1,
  9989. + .active_low = 1,
  9990. + }
  9991. +};
  9992. +
  9993. +static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = {
  9994. + {
  9995. + .name = "zcn-1523h:red:weak",
  9996. + .gpio = ZCN_1523H_2_GPIO_LED_WEAK,
  9997. + .active_low = 1,
  9998. + }, {
  9999. + .name = "zcn-1523h:amber:medium",
  10000. + .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM,
  10001. + .active_low = 1,
  10002. + }, {
  10003. + .name = "zcn-1523h:green:strong",
  10004. + .gpio = ZCN_1523H_2_GPIO_LED_STRONG,
  10005. + .active_low = 1,
  10006. + }
  10007. +};
  10008. +
  10009. +static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = {
  10010. + {
  10011. + .name = "zcn-1523h:red:weak",
  10012. + .gpio = ZCN_1523H_5_GPIO_LED_WEAK,
  10013. + .active_low = 1,
  10014. + }, {
  10015. + .name = "zcn-1523h:amber:medium",
  10016. + .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM,
  10017. + .active_low = 1,
  10018. + }, {
  10019. + .name = "zcn-1523h:green:strong",
  10020. + .gpio = ZCN_1523H_5_GPIO_LED_STRONG,
  10021. + .active_low = 1,
  10022. + }, {
  10023. + .name = "zcn-1523h:green:lan2",
  10024. + .gpio = ZCN_1523H_5_GPIO_LED_LAN2,
  10025. + .active_low = 1,
  10026. + }, {
  10027. + .name = "zcn-1523h:amber:unknown",
  10028. + .gpio = ZCN_1523H_5_GPIO_LED_UNKNOWN,
  10029. + }
  10030. +};
  10031. +
  10032. +static void __init zcn_1523h_generic_setup(void)
  10033. +{
  10034. + u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004);
  10035. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  10036. +
  10037. + ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
  10038. + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
  10039. + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
  10040. + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
  10041. + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
  10042. +
  10043. + ar71xx_add_device_m25p80(&zcn_1523h_flash_data);
  10044. +
  10045. + ar71xx_add_device_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio),
  10046. + zcn_1523h_leds_gpio);
  10047. +
  10048. + ar71xx_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL,
  10049. + ARRAY_SIZE(zcn_1523h_gpio_keys),
  10050. + zcn_1523h_gpio_keys);
  10051. +
  10052. + ap91_pci_init(ee, mac);
  10053. +
  10054. + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0);
  10055. + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1);
  10056. +
  10057. + /* LAN1 port */
  10058. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  10059. + ar71xx_eth0_data.speed = SPEED_100;
  10060. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  10061. +
  10062. + /* LAN2 port */
  10063. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  10064. + ar71xx_eth1_data.speed = SPEED_1000;
  10065. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  10066. +
  10067. + ar71xx_add_device_mdio(0x0);
  10068. + ar71xx_add_device_eth(0);
  10069. +}
  10070. +
  10071. +static void __init zcn_1523h_2_setup(void)
  10072. +{
  10073. + zcn_1523h_generic_setup();
  10074. + ap91_pci_setup_wmac_gpio(BIT(9), 0);
  10075. +
  10076. + ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio),
  10077. + zcn_1523h_2_leds_gpio);
  10078. +}
  10079. +
  10080. +MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2",
  10081. + zcn_1523h_2_setup);
  10082. +
  10083. +static void __init zcn_1523h_5_setup(void)
  10084. +{
  10085. + zcn_1523h_generic_setup();
  10086. + ap91_pci_setup_wmac_gpio(BIT(8), 0);
  10087. +
  10088. + ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio),
  10089. + zcn_1523h_5_leds_gpio);
  10090. + ar71xx_add_device_eth(1);
  10091. +}
  10092. +
  10093. +MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5",
  10094. + zcn_1523h_5_setup);
  10095. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h
  10096. --- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100
  10097. +++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-08-24 18:17:23.000000000 +0200
  10098. @@ -0,0 +1,75 @@
  10099. +/*
  10100. + * Atheros AR71xx machine type definitions
  10101. + *
  10102. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  10103. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  10104. + *
  10105. + * This program is free software; you can redistribute it and/or modify it
  10106. + * under the terms of the GNU General Public License version 2 as published
  10107. + * by the Free Software Foundation.
  10108. + */
  10109. +
  10110. +#ifndef _AR71XX_MACHTYPE_H
  10111. +#define _AR71XX_MACHTYPE_H
  10112. +
  10113. +#include <asm/mips_machine.h>
  10114. +
  10115. +enum ar71xx_mach_type {
  10116. + AR71XX_MACH_GENERIC = 0,
  10117. + AR71XX_MACH_AP121, /* Atheros AP121 */
  10118. + AR71XX_MACH_AP121_MINI, /* Atheros AP121-MINI */
  10119. + AR71XX_MACH_AP81, /* Atheros AP81 */
  10120. + AR71XX_MACH_AP83, /* Atheros AP83 */
  10121. + AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */
  10122. + AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */
  10123. + AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */
  10124. + AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */
  10125. + AR71XX_MACH_JA76PF, /* jjPlus JA76PF */
  10126. + AR71XX_MACH_JWAP003, /* jjPlus JWAP003 */
  10127. + AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */
  10128. + AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */
  10129. + AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */
  10130. + AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */
  10131. + AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */
  10132. + AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */
  10133. + AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */
  10134. + AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */
  10135. + AR71XX_MACH_PB42, /* Atheros PB42 */
  10136. + AR71XX_MACH_PB44, /* Atheros PB44 */
  10137. + AR71XX_MACH_PB92, /* Atheros PB92 */
  10138. + AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */
  10139. + AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */
  10140. + AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */
  10141. + AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */
  10142. + AR71XX_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */
  10143. + AR71XX_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */
  10144. + AR71XX_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */
  10145. + AR71XX_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */
  10146. + AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */
  10147. + AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */
  10148. + AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */
  10149. + AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */
  10150. + AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */
  10151. + AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */
  10152. + AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */
  10153. + AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
  10154. + AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */
  10155. + AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
  10156. + AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
  10157. + AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */
  10158. + AR71XX_MACH_WNDR3700V2, /* NETGEAR WNDR3700v2 */
  10159. + AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */
  10160. + AR71XX_MACH_WP543, /* Compex WP543 */
  10161. + AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */
  10162. + AR71XX_MACH_WRT400N, /* Linksys WRT400N */
  10163. + AR71XX_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */
  10164. + AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */
  10165. + AR71XX_MACH_EAP7660D, /* Senao EAP7660D */
  10166. + AR71XX_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */
  10167. + AR71XX_MACH_ZCN_1523H_5, /* Zcomax ZCN-1523H-5-xx */
  10168. + AR71XX_MACH_AP96, /* Atheros AP96 */
  10169. + AR71XX_MACH_UBNT_UNIFI, /* Unifi */
  10170. + AR71XX_MACH_DB120, /* Atheros DB120 (AR934x based) */
  10171. +};
  10172. +
  10173. +#endif /* _AR71XX_MACHTYPE_H */
  10174. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c
  10175. --- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
  10176. +++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-08-24 18:17:23.000000000 +0200
  10177. @@ -0,0 +1,75 @@
  10178. +/*
  10179. + * Atheros AR71xx minimal nvram support
  10180. + *
  10181. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10182. + *
  10183. + * This program is free software; you can redistribute it and/or modify it
  10184. + * under the terms of the GNU General Public License version 2 as published
  10185. + * by the Free Software Foundation.
  10186. + */
  10187. +
  10188. +#include <linux/kernel.h>
  10189. +#include <linux/vmalloc.h>
  10190. +#include <linux/errno.h>
  10191. +#include <linux/init.h>
  10192. +#include <linux/string.h>
  10193. +
  10194. +#include "nvram.h"
  10195. +
  10196. +char *nvram_find_var(const char *name, const char *buf, unsigned buf_len)
  10197. +{
  10198. + unsigned len = strlen(name);
  10199. + char *cur, *last;
  10200. +
  10201. + if (buf_len == 0 || len == 0)
  10202. + return NULL;
  10203. +
  10204. + if (buf_len < len)
  10205. + return NULL;
  10206. +
  10207. + if (len == 1)
  10208. + return memchr(buf, (int) *name, buf_len);
  10209. +
  10210. + last = (char *) buf + buf_len - len;
  10211. + for (cur = (char *) buf; cur <= last; cur++)
  10212. + if (cur[0] == name[0] && memcmp(cur, name, len) == 0)
  10213. + return cur + len;
  10214. +
  10215. + return NULL;
  10216. +}
  10217. +
  10218. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  10219. + const char *name, char *mac)
  10220. +{
  10221. + char *buf;
  10222. + char *mac_str;
  10223. + int ret;
  10224. + int t;
  10225. +
  10226. + buf = vmalloc(nvram_len);
  10227. + if (!buf)
  10228. + return -ENOMEM;
  10229. +
  10230. + memcpy(buf, nvram, nvram_len);
  10231. + buf[nvram_len - 1] = '\0';
  10232. +
  10233. + mac_str = nvram_find_var(name, buf, nvram_len);
  10234. + if (!mac_str) {
  10235. + ret = -EINVAL;
  10236. + goto free;
  10237. + }
  10238. +
  10239. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  10240. + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
  10241. +
  10242. + if (t != 6) {
  10243. + ret = -EINVAL;
  10244. + goto free;
  10245. + }
  10246. +
  10247. + ret = 0;
  10248. +
  10249. +free:
  10250. + vfree(buf);
  10251. + return ret;
  10252. +}
  10253. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h
  10254. --- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100
  10255. +++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-08-24 18:17:23.000000000 +0200
  10256. @@ -0,0 +1,19 @@
  10257. +/*
  10258. + * Atheros AR71xx minimal nvram support
  10259. + *
  10260. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10261. + *
  10262. + * This program is free software; you can redistribute it and/or modify it
  10263. + * under the terms of the GNU General Public License version 2 as published
  10264. + * by the Free Software Foundation.
  10265. + */
  10266. +
  10267. +#ifndef _AR71XX_NVRAM_H
  10268. +#define _AR71XX_NVRAM_H
  10269. +
  10270. +char *nvram_find_var(const char *name, const char *buf,
  10271. + unsigned buf_len) __init;
  10272. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  10273. + const char *name, char *mac) __init;
  10274. +
  10275. +#endif /* _AR71XX_NVRAM_H */
  10276. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c
  10277. --- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c 1970-01-01 01:00:00.000000000 +0100
  10278. +++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c 2011-08-24 18:17:23.000000000 +0200
  10279. @@ -0,0 +1,123 @@
  10280. +/*
  10281. + * Atheros AP94 reference board PCI initialization
  10282. + *
  10283. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  10284. + *
  10285. + * This program is free software; you can redistribute it and/or modify it
  10286. + * under the terms of the GNU General Public License version 2 as published
  10287. + * by the Free Software Foundation.
  10288. + */
  10289. +
  10290. +#include <linux/pci.h>
  10291. +#include <linux/delay.h>
  10292. +
  10293. +#include <asm/mach-ar71xx/ar71xx.h>
  10294. +#include <asm/mach-ar71xx/pci.h>
  10295. +
  10296. +struct ath9k_fixup {
  10297. + u16 *cal_data;
  10298. + unsigned slot;
  10299. +};
  10300. +
  10301. +static int ath9k_num_fixups;
  10302. +static struct ath9k_fixup ath9k_fixups[2];
  10303. +
  10304. +static void ath9k_pci_fixup(struct pci_dev *dev)
  10305. +{
  10306. + void __iomem *mem;
  10307. + u16 *cal_data = NULL;
  10308. + u16 cmd;
  10309. + u32 bar0;
  10310. + u32 val;
  10311. + unsigned i;
  10312. +
  10313. + for (i = 0; i < ath9k_num_fixups; i++) {
  10314. + if (ath9k_fixups[i].cal_data == NULL)
  10315. + continue;
  10316. +
  10317. + if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn))
  10318. + continue;
  10319. +
  10320. + cal_data = ath9k_fixups[i].cal_data;
  10321. + break;
  10322. + }
  10323. +
  10324. + if (cal_data == NULL)
  10325. + return;
  10326. +
  10327. + if (*cal_data != 0xa55a) {
  10328. + pr_err("pci %s: invalid calibration data\n", pci_name(dev));
  10329. + return;
  10330. + }
  10331. +
  10332. + pr_info("pci %s: fixup device configuration\n", pci_name(dev));
  10333. +
  10334. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  10335. + if (!mem) {
  10336. + pr_err("pci %s: ioremap error\n", pci_name(dev));
  10337. + return;
  10338. + }
  10339. +
  10340. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  10341. +
  10342. + switch (ar71xx_soc) {
  10343. + case AR71XX_SOC_AR7161:
  10344. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
  10345. + AR71XX_PCI_MEM_BASE);
  10346. + break;
  10347. + case AR71XX_SOC_AR7240:
  10348. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
  10349. + break;
  10350. +
  10351. + case AR71XX_SOC_AR7241:
  10352. + case AR71XX_SOC_AR7242:
  10353. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff);
  10354. + break;
  10355. +
  10356. + default:
  10357. + BUG();
  10358. + }
  10359. +
  10360. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  10361. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  10362. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  10363. +
  10364. + /* set pointer to first reg address */
  10365. + cal_data += 3;
  10366. + while (*cal_data != 0xffff) {
  10367. + u32 reg;
  10368. + reg = *cal_data++;
  10369. + val = *cal_data++;
  10370. + val |= (*cal_data++) << 16;
  10371. +
  10372. + __raw_writel(val, mem + reg);
  10373. + udelay(100);
  10374. + }
  10375. +
  10376. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  10377. + dev->vendor = val & 0xffff;
  10378. + dev->device = (val >> 16) & 0xffff;
  10379. +
  10380. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  10381. + dev->revision = val & 0xff;
  10382. + dev->class = val >> 8; /* upper 3 bytes */
  10383. +
  10384. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  10385. + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
  10386. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  10387. +
  10388. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
  10389. +
  10390. + iounmap(mem);
  10391. +}
  10392. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
  10393. +
  10394. +void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data)
  10395. +{
  10396. + if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
  10397. + return;
  10398. +
  10399. + ath9k_fixups[ath9k_num_fixups].slot = slot;
  10400. + ath9k_fixups[ath9k_num_fixups].cal_data = cal_data;
  10401. + ath9k_num_fixups++;
  10402. +}
  10403. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h
  10404. --- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h 1970-01-01 01:00:00.000000000 +0100
  10405. +++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h 2011-08-24 18:17:23.000000000 +0200
  10406. @@ -0,0 +1,6 @@
  10407. +#ifndef _PCI_ATH9K_FIXUP
  10408. +#define _PCI_ATH9K_FIXUP
  10409. +
  10410. +void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init;
  10411. +
  10412. +#endif /* _PCI_ATH9K_FIXUP */
  10413. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c
  10414. --- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100
  10415. +++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-08-24 18:17:23.000000000 +0200
  10416. @@ -0,0 +1,97 @@
  10417. +/*
  10418. + * Atheros AR71xx PCI setup code
  10419. + *
  10420. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  10421. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  10422. + *
  10423. + * Parts of this file are based on Atheros' 2.6.15 BSP
  10424. + *
  10425. + * This program is free software; you can redistribute it and/or modify it
  10426. + * under the terms of the GNU General Public License version 2 as published
  10427. + * by the Free Software Foundation.
  10428. + */
  10429. +
  10430. +#include <linux/kernel.h>
  10431. +
  10432. +#include <asm/traps.h>
  10433. +
  10434. +#include <asm/mach-ar71xx/ar71xx.h>
  10435. +#include <asm/mach-ar71xx/pci.h>
  10436. +
  10437. +unsigned ar71xx_pci_nr_irqs __initdata;
  10438. +struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  10439. +
  10440. +int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  10441. +
  10442. +static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
  10443. +{
  10444. + int err = 0;
  10445. +
  10446. + err = ar71xx_pci_be_handler(is_fixup);
  10447. +
  10448. + return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  10449. +}
  10450. +
  10451. +int pcibios_plat_dev_init(struct pci_dev *dev)
  10452. +{
  10453. + if (ar71xx_pci_plat_dev_init)
  10454. + return ar71xx_pci_plat_dev_init(dev);
  10455. +
  10456. + return 0;
  10457. +}
  10458. +
  10459. +int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
  10460. +{
  10461. + int ret = 0;
  10462. +
  10463. + switch (ar71xx_soc) {
  10464. + case AR71XX_SOC_AR7130:
  10465. + case AR71XX_SOC_AR7141:
  10466. + case AR71XX_SOC_AR7161:
  10467. + ret = ar71xx_pcibios_map_irq(dev, slot, pin);
  10468. + break;
  10469. +
  10470. + case AR71XX_SOC_AR7240:
  10471. + case AR71XX_SOC_AR7241:
  10472. + case AR71XX_SOC_AR7242:
  10473. + case AR71XX_SOC_AR9342:
  10474. + case AR71XX_SOC_AR9344:
  10475. + ret = ar724x_pcibios_map_irq(dev, slot, pin);
  10476. + break;
  10477. +
  10478. + default:
  10479. + break;
  10480. + }
  10481. +
  10482. + return ret;
  10483. +}
  10484. +
  10485. +int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  10486. +{
  10487. + int ret = 0;
  10488. +
  10489. + switch (ar71xx_soc) {
  10490. + case AR71XX_SOC_AR7130:
  10491. + case AR71XX_SOC_AR7141:
  10492. + case AR71XX_SOC_AR7161:
  10493. + board_be_handler = ar71xx_be_handler;
  10494. + ret = ar71xx_pcibios_init();
  10495. + break;
  10496. +
  10497. + case AR71XX_SOC_AR7240:
  10498. + case AR71XX_SOC_AR7241:
  10499. + case AR71XX_SOC_AR7242:
  10500. + case AR71XX_SOC_AR9342:
  10501. + case AR71XX_SOC_AR9344:
  10502. + ret = ar724x_pcibios_init();
  10503. + break;
  10504. +
  10505. + default:
  10506. + return 0;
  10507. + }
  10508. +
  10509. + ar71xx_pci_nr_irqs = nr_irqs;
  10510. + ar71xx_pci_irq_map = map;
  10511. +
  10512. + return ret;
  10513. +}
  10514. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c
  10515. --- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100
  10516. +++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-08-24 18:17:23.000000000 +0200
  10517. @@ -0,0 +1,189 @@
  10518. +/*
  10519. + * Atheros AR71xx SoC specific prom routines
  10520. + *
  10521. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  10522. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  10523. + *
  10524. + * This program is free software; you can redistribute it and/or modify it
  10525. + * under the terms of the GNU General Public License version 2 as published
  10526. + * by the Free Software Foundation.
  10527. + */
  10528. +
  10529. +#include <linux/kernel.h>
  10530. +#include <linux/init.h>
  10531. +#include <linux/io.h>
  10532. +#include <linux/string.h>
  10533. +
  10534. +#include <asm/bootinfo.h>
  10535. +#include <asm/addrspace.h>
  10536. +#include <asm/fw/myloader/myloader.h>
  10537. +
  10538. +#include <asm/mach-ar71xx/ar71xx.h>
  10539. +
  10540. +static inline int is_valid_ram_addr(void *addr)
  10541. +{
  10542. + if (((u32) addr > KSEG0) &&
  10543. + ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX)))
  10544. + return 1;
  10545. +
  10546. + if (((u32) addr > KSEG1) &&
  10547. + ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX)))
  10548. + return 1;
  10549. +
  10550. + return 0;
  10551. +}
  10552. +
  10553. +static void __init ar71xx_prom_append_cmdline(const char *name,
  10554. + const char *value)
  10555. +{
  10556. + char buf[COMMAND_LINE_SIZE];
  10557. +
  10558. + snprintf(buf, sizeof(buf), " %s=%s", name, value);
  10559. + strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline));
  10560. +}
  10561. +
  10562. +static const char * __init ar71xx_prom_find_env(char **envp, const char *name)
  10563. +{
  10564. + const char *ret = NULL;
  10565. + int len;
  10566. + char **p;
  10567. +
  10568. + if (!is_valid_ram_addr(envp))
  10569. + return NULL;
  10570. +
  10571. + len = strlen(name);
  10572. + for (p = envp; is_valid_ram_addr(*p); p++) {
  10573. + if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') {
  10574. + ret = *p + len + 1;
  10575. + break;
  10576. + }
  10577. +
  10578. + /* RedBoot env comes in pointer pairs - key, value */
  10579. + if (strncmp(name, *p, len) == 0 && (*p)[len] == 0)
  10580. + if (is_valid_ram_addr(*(++p))) {
  10581. + ret = *p;
  10582. + break;
  10583. + }
  10584. + }
  10585. +
  10586. + return ret;
  10587. +}
  10588. +
  10589. +static int __init ar71xx_prom_init_myloader(void)
  10590. +{
  10591. + struct myloader_info *mylo;
  10592. + char mac_buf[32];
  10593. + char *mac;
  10594. +
  10595. + mylo = myloader_get_info();
  10596. + if (!mylo)
  10597. + return 0;
  10598. +
  10599. + switch (mylo->did) {
  10600. + case DEVID_COMPEX_WP543:
  10601. + ar71xx_prom_append_cmdline("board", "WP543");
  10602. + break;
  10603. + default:
  10604. + printk(KERN_WARNING "prom: unknown device id: %x\n",
  10605. + mylo->did);
  10606. + return 0;
  10607. + }
  10608. +
  10609. + mac = mylo->macs[0];
  10610. + snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
  10611. + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  10612. +
  10613. + ar71xx_prom_append_cmdline("ethaddr", mac_buf);
  10614. +
  10615. + return 1;
  10616. +}
  10617. +
  10618. +#ifdef CONFIG_IMAGE_CMDLINE_HACK
  10619. +extern char __image_cmdline[];
  10620. +
  10621. +static int __init ar71xx_use__image_cmdline(void)
  10622. +{
  10623. + char *p = __image_cmdline;
  10624. + int replace = 0;
  10625. +
  10626. + if (*p == '-') {
  10627. + replace = 1;
  10628. + p++;
  10629. + }
  10630. +
  10631. + if (*p == '\0')
  10632. + return 0;
  10633. +
  10634. + if (replace) {
  10635. + strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
  10636. + } else {
  10637. + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
  10638. + strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
  10639. + }
  10640. +
  10641. + return 1;
  10642. +}
  10643. +#else
  10644. +static inline int ar71xx_use__image_cmdline(void) { return 0; }
  10645. +#endif
  10646. +
  10647. +static __init void ar71xx_prom_init_cmdline(int argc, char **argv)
  10648. +{
  10649. + int i;
  10650. +
  10651. + if (ar71xx_use__image_cmdline())
  10652. + return;
  10653. +
  10654. + if (!is_valid_ram_addr(argv))
  10655. + return;
  10656. +
  10657. + for (i = 0; i < argc; i++)
  10658. + if (is_valid_ram_addr(argv[i])) {
  10659. + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
  10660. + strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
  10661. + }
  10662. +}
  10663. +
  10664. +void __init prom_init(void)
  10665. +{
  10666. + const char *env;
  10667. + char **envp;
  10668. +
  10669. + printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, "
  10670. + "fw_arg2=%08x, fw_arg3=%08x\n",
  10671. + (unsigned int)fw_arg0, (unsigned int)fw_arg1,
  10672. + (unsigned int)fw_arg2, (unsigned int)fw_arg3);
  10673. +
  10674. +
  10675. + if (ar71xx_prom_init_myloader())
  10676. + return;
  10677. +
  10678. + ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
  10679. +
  10680. + envp = (char **)fw_arg2;
  10681. + if (!strstr(arcs_cmdline, "ethaddr=")) {
  10682. + env = ar71xx_prom_find_env(envp, "ethaddr");
  10683. + if (env)
  10684. + ar71xx_prom_append_cmdline("ethaddr", env);
  10685. + }
  10686. +
  10687. + if (!strstr(arcs_cmdline, "board=")) {
  10688. + env = ar71xx_prom_find_env(envp, "board");
  10689. + if (env) {
  10690. + /* Workaround for buggy bootloaders */
  10691. + if (strcmp(env, "RouterStation") == 0 ||
  10692. + strcmp(env, "Ubiquiti AR71xx-based board") == 0)
  10693. + env = "UBNT-RS";
  10694. +
  10695. + if (strcmp(env, "RouterStation PRO") == 0)
  10696. + env = "UBNT-RSPRO";
  10697. +
  10698. + ar71xx_prom_append_cmdline("board", env);
  10699. + }
  10700. + }
  10701. +}
  10702. +
  10703. +void __init prom_free_prom_memory(void)
  10704. +{
  10705. + /* We do not have to prom memory to free */
  10706. +}
  10707. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c
  10708. --- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100
  10709. +++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-08-24 18:17:23.000000000 +0200
  10710. @@ -0,0 +1,446 @@
  10711. +/*
  10712. + * Atheros AR71xx SoC specific setup
  10713. + *
  10714. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  10715. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  10716. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  10717. + *
  10718. + * Parts of this file are based on Atheros 2.6.15 BSP
  10719. + * Parts of this file are based on Atheros 2.6.31 BSP
  10720. + *
  10721. + * This program is free software; you can redistribute it and/or modify it
  10722. + * under the terms of the GNU General Public License version 2 as published
  10723. + * by the Free Software Foundation.
  10724. + */
  10725. +
  10726. +#include <linux/kernel.h>
  10727. +#include <linux/init.h>
  10728. +#include <linux/bootmem.h>
  10729. +
  10730. +#include <asm/bootinfo.h>
  10731. +#include <asm/time.h> /* for mips_hpt_frequency */
  10732. +#include <asm/reboot.h> /* for _machine_{restart,halt} */
  10733. +#include <asm/mips_machine.h>
  10734. +
  10735. +#include <asm/mach-ar71xx/ar71xx.h>
  10736. +
  10737. +#include "machtype.h"
  10738. +#include "devices.h"
  10739. +
  10740. +#define AR71XX_SYS_TYPE_LEN 64
  10741. +
  10742. +u32 ar71xx_cpu_freq;
  10743. +EXPORT_SYMBOL_GPL(ar71xx_cpu_freq);
  10744. +
  10745. +u32 ar71xx_ahb_freq;
  10746. +EXPORT_SYMBOL_GPL(ar71xx_ahb_freq);
  10747. +
  10748. +u32 ar71xx_ddr_freq;
  10749. +EXPORT_SYMBOL_GPL(ar71xx_ddr_freq);
  10750. +
  10751. +u32 ar71xx_ref_freq;
  10752. +EXPORT_SYMBOL_GPL(ar71xx_ref_freq);
  10753. +
  10754. +enum ar71xx_soc_type ar71xx_soc;
  10755. +EXPORT_SYMBOL_GPL(ar71xx_soc);
  10756. +
  10757. +u32 ar71xx_soc_rev;
  10758. +EXPORT_SYMBOL_GPL(ar71xx_soc_rev);
  10759. +
  10760. +static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];
  10761. +
  10762. +static void ar71xx_restart(char *command)
  10763. +{
  10764. + ar71xx_device_stop(RESET_MODULE_FULL_CHIP);
  10765. + for (;;)
  10766. + if (cpu_wait)
  10767. + cpu_wait();
  10768. +}
  10769. +
  10770. +static void ar71xx_halt(void)
  10771. +{
  10772. + while (1)
  10773. + cpu_wait();
  10774. +}
  10775. +
  10776. +static void __init ar71xx_detect_mem_size(void)
  10777. +{
  10778. + unsigned long size;
  10779. +
  10780. + for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX;
  10781. + size <<= 1) {
  10782. + if (!memcmp(ar71xx_detect_mem_size,
  10783. + ar71xx_detect_mem_size + size, 1024))
  10784. + break;
  10785. + }
  10786. +
  10787. + add_memory_region(0, size, BOOT_MEM_RAM);
  10788. +}
  10789. +
  10790. +static void __init ar71xx_detect_sys_type(void)
  10791. +{
  10792. + char *chip = "????";
  10793. + u32 id;
  10794. + u32 major;
  10795. + u32 minor;
  10796. + u32 rev = 0;
  10797. +
  10798. + id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID);
  10799. + major = id & REV_ID_MAJOR_MASK;
  10800. +
  10801. + switch (major) {
  10802. + case REV_ID_MAJOR_AR71XX:
  10803. + minor = id & AR71XX_REV_ID_MINOR_MASK;
  10804. + rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
  10805. + rev &= AR71XX_REV_ID_REVISION_MASK;
  10806. + switch (minor) {
  10807. + case AR71XX_REV_ID_MINOR_AR7130:
  10808. + ar71xx_soc = AR71XX_SOC_AR7130;
  10809. + chip = "7130";
  10810. + break;
  10811. +
  10812. + case AR71XX_REV_ID_MINOR_AR7141:
  10813. + ar71xx_soc = AR71XX_SOC_AR7141;
  10814. + chip = "7141";
  10815. + break;
  10816. +
  10817. + case AR71XX_REV_ID_MINOR_AR7161:
  10818. + ar71xx_soc = AR71XX_SOC_AR7161;
  10819. + chip = "7161";
  10820. + break;
  10821. + }
  10822. + break;
  10823. +
  10824. + case REV_ID_MAJOR_AR7240:
  10825. + ar71xx_soc = AR71XX_SOC_AR7240;
  10826. + chip = "7240";
  10827. + rev = id & AR724X_REV_ID_REVISION_MASK;
  10828. + break;
  10829. +
  10830. + case REV_ID_MAJOR_AR7241:
  10831. + ar71xx_soc = AR71XX_SOC_AR7241;
  10832. + chip = "7241";
  10833. + rev = id & AR724X_REV_ID_REVISION_MASK;
  10834. + break;
  10835. +
  10836. + case REV_ID_MAJOR_AR7242:
  10837. + ar71xx_soc = AR71XX_SOC_AR7242;
  10838. + chip = "7242";
  10839. + rev = id & AR724X_REV_ID_REVISION_MASK;
  10840. + break;
  10841. +
  10842. + case REV_ID_MAJOR_AR913X:
  10843. + minor = id & AR91XX_REV_ID_MINOR_MASK;
  10844. + rev = id >> AR91XX_REV_ID_REVISION_SHIFT;
  10845. + rev &= AR91XX_REV_ID_REVISION_MASK;
  10846. + switch (minor) {
  10847. + case AR91XX_REV_ID_MINOR_AR9130:
  10848. + ar71xx_soc = AR71XX_SOC_AR9130;
  10849. + chip = "9130";
  10850. + break;
  10851. +
  10852. + case AR91XX_REV_ID_MINOR_AR9132:
  10853. + ar71xx_soc = AR71XX_SOC_AR9132;
  10854. + chip = "9132";
  10855. + break;
  10856. + }
  10857. + break;
  10858. +
  10859. + case REV_ID_MAJOR_AR9330:
  10860. + ar71xx_soc = AR71XX_SOC_AR9330;
  10861. + chip = "9330";
  10862. + rev = id & AR933X_REV_ID_REVISION_MASK;
  10863. + break;
  10864. +
  10865. + case REV_ID_MAJOR_AR9331:
  10866. + ar71xx_soc = AR71XX_SOC_AR9331;
  10867. + chip = "9331";
  10868. + rev = id & AR933X_REV_ID_REVISION_MASK;
  10869. + break;
  10870. +
  10871. + case REV_ID_MAJOR_AR9342:
  10872. + ar71xx_soc = AR71XX_SOC_AR9342;
  10873. + chip = "9342";
  10874. + rev = id & AR934X_REV_ID_REVISION_MASK;
  10875. + break;
  10876. +
  10877. + case REV_ID_MAJOR_AR9344:
  10878. + ar71xx_soc = AR71XX_SOC_AR9344;
  10879. + chip = "9344";
  10880. + rev = id & AR934X_REV_ID_REVISION_MASK;
  10881. + break;
  10882. +
  10883. + default:
  10884. + panic("ar71xx: unknown chip id:0x%08x\n", id);
  10885. + }
  10886. +
  10887. + ar71xx_soc_rev = rev;
  10888. +
  10889. + sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev);
  10890. + pr_info("SoC: %s\n", ar71xx_sys_type);
  10891. +}
  10892. +
  10893. +static void __init ar934x_detect_sys_frequency(void)
  10894. +{
  10895. + u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
  10896. +
  10897. + if (ar71xx_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & AR934X_REF_CLK_40)
  10898. + ar71xx_ref_freq = 40 * 1000 * 1000;
  10899. + else
  10900. + ar71xx_ref_freq = 25 * 1000 * 1000;
  10901. +
  10902. + clk_ctrl = ar71xx_pll_rr(AR934X_PLL_REG_DDR_CTRL_CLOCK);
  10903. +
  10904. + pll = ar71xx_pll_rr(AR934X_PLL_REG_CPU_CONFIG);
  10905. + out_div = AR934X_CPU_PLL_CFG_OUTDIV_GET(pll);
  10906. + ref_div = AR934X_CPU_PLL_CFG_REFDIV_GET(pll);
  10907. + nint = AR934X_CPU_PLL_CFG_NINT_GET(pll);
  10908. + frac = AR934X_CPU_PLL_CFG_NFRAC_GET(pll);
  10909. + postdiv = AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(clk_ctrl);
  10910. + ar71xx_cpu_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) /
  10911. + (postdiv + 1);
  10912. +
  10913. + out_div = AR934X_DDR_PLL_CFG_OUTDIV_GET(pll);
  10914. + ref_div = AR934X_DDR_PLL_CFG_REFDIV_GET(pll);
  10915. + nint = AR934X_DDR_PLL_CFG_NINT_GET(pll);
  10916. + frac = AR934X_DDR_PLL_CFG_NFRAC_GET(pll);
  10917. + postdiv = AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(clk_ctrl);
  10918. + ar71xx_ddr_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) /
  10919. + (postdiv + 1);
  10920. +
  10921. + postdiv = AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(clk_ctrl);
  10922. +
  10923. + if (AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(clk_ctrl)) {
  10924. + ar71xx_ahb_freq = ar71xx_ddr_freq / (postdiv + 1);
  10925. + } else {
  10926. + ar71xx_ahb_freq = ar71xx_cpu_freq / (postdiv + 1);
  10927. + }
  10928. +
  10929. +}
  10930. +
  10931. +static void __init ar91xx_detect_sys_frequency(void)
  10932. +{
  10933. + u32 pll;
  10934. + u32 freq;
  10935. + u32 div;
  10936. +
  10937. + ar71xx_ref_freq = 5 * 1000 * 1000;
  10938. +
  10939. + pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
  10940. +
  10941. + div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
  10942. + freq = div * ar71xx_ref_freq;
  10943. +
  10944. + ar71xx_cpu_freq = freq;
  10945. +
  10946. + div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1;
  10947. + ar71xx_ddr_freq = freq / div;
  10948. +
  10949. + div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2;
  10950. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  10951. +}
  10952. +
  10953. +static void __init ar71xx_detect_sys_frequency(void)
  10954. +{
  10955. + u32 pll;
  10956. + u32 freq;
  10957. + u32 div;
  10958. +
  10959. + ar71xx_ref_freq = 40 * 1000 * 1000;
  10960. +
  10961. + pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
  10962. +
  10963. + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
  10964. + freq = div * ar71xx_ref_freq;
  10965. +
  10966. + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
  10967. + ar71xx_cpu_freq = freq / div;
  10968. +
  10969. + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
  10970. + ar71xx_ddr_freq = freq / div;
  10971. +
  10972. + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
  10973. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  10974. +}
  10975. +
  10976. +static void __init ar724x_detect_sys_frequency(void)
  10977. +{
  10978. + u32 pll;
  10979. + u32 freq;
  10980. + u32 div;
  10981. +
  10982. + ar71xx_ref_freq = 5 * 1000 * 1000;
  10983. +
  10984. + pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
  10985. +
  10986. + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
  10987. + freq = div * ar71xx_ref_freq;
  10988. +
  10989. + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
  10990. + freq *= div;
  10991. +
  10992. + ar71xx_cpu_freq = freq;
  10993. +
  10994. + div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
  10995. + ar71xx_ddr_freq = freq / div;
  10996. +
  10997. + div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
  10998. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  10999. +}
  11000. +
  11001. +static void __init ar933x_detect_sys_frequency(void)
  11002. +{
  11003. + u32 clock_ctrl;
  11004. + u32 cpu_config;
  11005. + u32 freq;
  11006. + u32 t;
  11007. +
  11008. + t = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
  11009. + if (t & AR933X_BOOTSTRAP_REF_CLK_40)
  11010. + ar71xx_ref_freq = (40 * 1000 * 1000);
  11011. + else
  11012. + ar71xx_ref_freq = (25 * 1000 * 1000);
  11013. +
  11014. + clock_ctrl = ar71xx_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
  11015. + if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
  11016. + ar71xx_cpu_freq = ar71xx_ref_freq;
  11017. + ar71xx_ahb_freq = ar71xx_ref_freq;
  11018. + ar71xx_ddr_freq = ar71xx_ref_freq;
  11019. + } else {
  11020. + cpu_config = ar71xx_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
  11021. +
  11022. + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
  11023. + AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
  11024. + freq = ar71xx_ref_freq / t;
  11025. +
  11026. + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
  11027. + AR933X_PLL_CPU_CONFIG_NINT_MASK;
  11028. + freq *= t;
  11029. +
  11030. + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
  11031. + AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
  11032. + if (t == 0)
  11033. + t = 1;
  11034. +
  11035. + freq >>= t;
  11036. +
  11037. + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
  11038. + AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
  11039. + ar71xx_cpu_freq = freq / t;
  11040. +
  11041. + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
  11042. + AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
  11043. + ar71xx_ddr_freq = freq / t;
  11044. +
  11045. + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
  11046. + AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
  11047. + ar71xx_ahb_freq = freq / t;
  11048. + }
  11049. +}
  11050. +
  11051. +static void __init detect_sys_frequency(void)
  11052. +{
  11053. + switch (ar71xx_soc) {
  11054. + case AR71XX_SOC_AR7130:
  11055. + case AR71XX_SOC_AR7141:
  11056. + case AR71XX_SOC_AR7161:
  11057. + ar71xx_detect_sys_frequency();
  11058. + break;
  11059. +
  11060. + case AR71XX_SOC_AR7240:
  11061. + case AR71XX_SOC_AR7241:
  11062. + case AR71XX_SOC_AR7242:
  11063. + ar724x_detect_sys_frequency();
  11064. + break;
  11065. +
  11066. + case AR71XX_SOC_AR9130:
  11067. + case AR71XX_SOC_AR9132:
  11068. + ar91xx_detect_sys_frequency();
  11069. + break;
  11070. +
  11071. + case AR71XX_SOC_AR9330:
  11072. + case AR71XX_SOC_AR9331:
  11073. + ar933x_detect_sys_frequency();
  11074. + break;
  11075. +
  11076. + case AR71XX_SOC_AR9341:
  11077. + case AR71XX_SOC_AR9342:
  11078. + case AR71XX_SOC_AR9344:
  11079. + ar934x_detect_sys_frequency();
  11080. + break;
  11081. + default:
  11082. + BUG();
  11083. + }
  11084. +}
  11085. +
  11086. +const char *get_system_type(void)
  11087. +{
  11088. + return ar71xx_sys_type;
  11089. +}
  11090. +
  11091. +unsigned int __cpuinit get_c0_compare_irq(void)
  11092. +{
  11093. + return CP0_LEGACY_COMPARE_IRQ;
  11094. +}
  11095. +
  11096. +void __init plat_mem_setup(void)
  11097. +{
  11098. + set_io_port_base(KSEG1);
  11099. +
  11100. + ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
  11101. + AR71XX_DDR_CTRL_SIZE);
  11102. +
  11103. + ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
  11104. + AR71XX_PLL_SIZE);
  11105. +
  11106. + ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
  11107. + AR71XX_RESET_SIZE);
  11108. +
  11109. + ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  11110. +
  11111. + ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE,
  11112. + AR71XX_USB_CTRL_SIZE);
  11113. +
  11114. + ar71xx_detect_mem_size();
  11115. + ar71xx_detect_sys_type();
  11116. + detect_sys_frequency();
  11117. +
  11118. + pr_info("Clocks: CPU:%u.%03uMHz, DDR:%u.%03uMHz, AHB:%u.%03uMHz, "
  11119. + "Ref:%u.%03uMHz",
  11120. + ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000,
  11121. + ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000,
  11122. + ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000,
  11123. + ar71xx_ref_freq / 1000000, (ar71xx_ref_freq / 1000) % 1000);
  11124. +
  11125. + _machine_restart = ar71xx_restart;
  11126. + _machine_halt = ar71xx_halt;
  11127. + pm_power_off = ar71xx_halt;
  11128. +}
  11129. +
  11130. +void __init plat_time_init(void)
  11131. +{
  11132. + mips_hpt_frequency = ar71xx_cpu_freq / 2;
  11133. +}
  11134. +
  11135. +__setup("board=", mips_machtype_setup);
  11136. +
  11137. +static int __init ar71xx_machine_setup(void)
  11138. +{
  11139. + ar71xx_gpio_init();
  11140. +
  11141. + ar71xx_add_device_uart();
  11142. + ar71xx_add_device_wdt();
  11143. +
  11144. + mips_machine_setup();
  11145. + return 0;
  11146. +}
  11147. +
  11148. +arch_initcall(ar71xx_machine_setup);
  11149. +
  11150. +static void __init ar71xx_generic_init(void)
  11151. +{
  11152. + /* Nothing to do */
  11153. +}
  11154. +
  11155. +MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board",
  11156. + ar71xx_generic_init);
  11157. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/checksum.h linux-2.6.39/arch/mips/include/asm/checksum.h
  11158. --- linux-2.6.39.orig/arch/mips/include/asm/checksum.h 2011-05-19 06:06:34.000000000 +0200
  11159. +++ linux-2.6.39/arch/mips/include/asm/checksum.h 2011-08-24 18:17:23.000000000 +0200
  11160. @@ -12,6 +12,7 @@
  11161. #define _ASM_CHECKSUM_H
  11162. #include <linux/in6.h>
  11163. +#include <linux/unaligned/packed_struct.h>
  11164. #include <asm/uaccess.h>
  11165. @@ -104,26 +105,30 @@
  11166. const unsigned int *stop = word + ihl;
  11167. unsigned int csum;
  11168. int carry;
  11169. + unsigned int w;
  11170. - csum = word[0];
  11171. - csum += word[1];
  11172. - carry = (csum < word[1]);
  11173. + csum = __get_unaligned_cpu32(word++);
  11174. +
  11175. + w = __get_unaligned_cpu32(word++);
  11176. + csum += w;
  11177. + carry = (csum < w);
  11178. csum += carry;
  11179. - csum += word[2];
  11180. - carry = (csum < word[2]);
  11181. + w = __get_unaligned_cpu32(word++);
  11182. + csum += w;
  11183. + carry = (csum < w);
  11184. csum += carry;
  11185. - csum += word[3];
  11186. - carry = (csum < word[3]);
  11187. + w = __get_unaligned_cpu32(word++);
  11188. + csum += w;
  11189. + carry = (csum < w);
  11190. csum += carry;
  11191. - word += 4;
  11192. do {
  11193. - csum += *word;
  11194. - carry = (csum < *word);
  11195. + w = __get_unaligned_cpu32(word++);
  11196. + csum += w;
  11197. + carry = (csum < w);
  11198. csum += carry;
  11199. - word++;
  11200. } while (word != stop);
  11201. return csum_fold(csum);
  11202. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h
  11203. --- linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100
  11204. +++ linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h 2011-08-24 18:17:23.000000000 +0200
  11205. @@ -0,0 +1,34 @@
  11206. +/*
  11207. + * Compex's MyLoader specific definitions
  11208. + *
  11209. + * Copyright (C) 2006-2008 Gabor Juhos <juhosg@openwrt.org>
  11210. + *
  11211. + * This program is free software; you can redistribute it and/or modify it
  11212. + * under the terms of the GNU General Public License version 2 as published
  11213. + * by the Free Software Foundation.
  11214. + *
  11215. + */
  11216. +
  11217. +#ifndef _ASM_MIPS_FW_MYLOADER_H
  11218. +#define _ASM_MIPS_FW_MYLOADER_H
  11219. +
  11220. +#include <linux/myloader.h>
  11221. +
  11222. +struct myloader_info {
  11223. + uint32_t vid;
  11224. + uint32_t did;
  11225. + uint32_t svid;
  11226. + uint32_t sdid;
  11227. + uint8_t macs[MYLO_ETHADDR_COUNT][6];
  11228. +};
  11229. +
  11230. +#ifdef CONFIG_MYLOADER
  11231. +extern struct myloader_info *myloader_get_info(void) __init;
  11232. +#else
  11233. +static inline struct myloader_info *myloader_get_info(void)
  11234. +{
  11235. + return NULL;
  11236. +}
  11237. +#endif /* CONFIG_MYLOADER */
  11238. +
  11239. +#endif /* _ASM_MIPS_FW_MYLOADER_H */
  11240. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h
  11241. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100
  11242. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-08-24 18:17:23.000000000 +0200
  11243. @@ -0,0 +1,769 @@
  11244. +/*
  11245. + * Atheros AR71xx SoC specific definitions
  11246. + *
  11247. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  11248. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  11249. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  11250. + *
  11251. + * Parts of this file are based on Atheros 2.6.15 BSP
  11252. + * Parts of this file are based on Atheros 2.6.31 BSP
  11253. + *
  11254. + * This program is free software; you can redistribute it and/or modify it
  11255. + * under the terms of the GNU General Public License version 2 as published
  11256. + * by the Free Software Foundation.
  11257. + */
  11258. +
  11259. +#ifndef __ASM_MACH_AR71XX_H
  11260. +#define __ASM_MACH_AR71XX_H
  11261. +
  11262. +#include <linux/types.h>
  11263. +#include <linux/init.h>
  11264. +#include <linux/io.h>
  11265. +#include <linux/bitops.h>
  11266. +
  11267. +#ifndef __ASSEMBLER__
  11268. +
  11269. +#define AR71XX_PCI_MEM_BASE 0x10000000
  11270. +#define AR71XX_PCI_MEM_SIZE 0x08000000
  11271. +#define AR71XX_APB_BASE 0x18000000
  11272. +#define AR71XX_GE0_BASE 0x19000000
  11273. +#define AR71XX_GE0_SIZE 0x01000000
  11274. +#define AR71XX_GE1_BASE 0x1a000000
  11275. +#define AR71XX_GE1_SIZE 0x01000000
  11276. +#define AR71XX_EHCI_BASE 0x1b000000
  11277. +#define AR71XX_EHCI_SIZE 0x01000000
  11278. +#define AR71XX_OHCI_BASE 0x1c000000
  11279. +#define AR71XX_OHCI_SIZE 0x01000000
  11280. +#define AR7240_OHCI_BASE 0x1b000000
  11281. +#define AR7240_OHCI_SIZE 0x01000000
  11282. +#define AR71XX_SPI_BASE 0x1f000000
  11283. +#define AR71XX_SPI_SIZE 0x01000000
  11284. +
  11285. +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
  11286. +#define AR71XX_DDR_CTRL_SIZE 0x10000
  11287. +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
  11288. +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  11289. +#define AR71XX_UART_SIZE 0x10000
  11290. +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
  11291. +#define AR71XX_USB_CTRL_SIZE 0x10000
  11292. +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
  11293. +#define AR71XX_GPIO_SIZE 0x10000
  11294. +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
  11295. +#define AR71XX_PLL_SIZE 0x10000
  11296. +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
  11297. +#define AR71XX_RESET_SIZE 0x10000
  11298. +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
  11299. +#define AR71XX_MII_SIZE 0x10000
  11300. +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
  11301. +#define AR71XX_SLIC_SIZE 0x10000
  11302. +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
  11303. +#define AR71XX_DMA_SIZE 0x10000
  11304. +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
  11305. +#define AR71XX_STEREO_SIZE 0x10000
  11306. +
  11307. +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
  11308. +#define AR724X_PCI_CRP_SIZE 0x100
  11309. +
  11310. +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
  11311. +#define AR724X_PCI_CTRL_SIZE 0x100
  11312. +
  11313. +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
  11314. +#define AR91XX_WMAC_SIZE 0x30000
  11315. +
  11316. +#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  11317. +#define AR933X_UART_SIZE 0x14
  11318. +#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
  11319. +#define AR933X_WMAC_SIZE 0x20000
  11320. +
  11321. +#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
  11322. +#define AR934X_WMAC_SIZE 0x20000
  11323. +
  11324. +#define AR71XX_MEM_SIZE_MIN 0x0200000
  11325. +#define AR71XX_MEM_SIZE_MAX 0x10000000
  11326. +
  11327. +#define AR71XX_CPU_IRQ_BASE 0
  11328. +#define AR71XX_MISC_IRQ_BASE 8
  11329. +#define AR71XX_MISC_IRQ_COUNT 32
  11330. +#define AR71XX_GPIO_IRQ_BASE 40
  11331. +#define AR71XX_GPIO_IRQ_COUNT 32
  11332. +#define AR71XX_PCI_IRQ_BASE 72
  11333. +#define AR71XX_PCI_IRQ_COUNT 8
  11334. +
  11335. +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
  11336. +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
  11337. +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
  11338. +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
  11339. +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
  11340. +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
  11341. +
  11342. +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
  11343. +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
  11344. +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
  11345. +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
  11346. +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
  11347. +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
  11348. +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
  11349. +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
  11350. +#define AR71XX_MISC_IRQ_TIMER2 (AR71XX_MISC_IRQ_BASE + 8)
  11351. +#define AR71XX_MISC_IRQ_TIMER3 (AR71XX_MISC_IRQ_BASE + 9)
  11352. +#define AR71XX_MISC_IRQ_TIMER4 (AR71XX_MISC_IRQ_BASE + 10)
  11353. +#define AR71XX_MISC_IRQ_DDR_PERF (AR71XX_MISC_IRQ_BASE + 11)
  11354. +#define AR71XX_MISC_IRQ_ENET_LINK (AR71XX_MISC_IRQ_BASE + 12)
  11355. +
  11356. +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
  11357. +
  11358. +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
  11359. +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
  11360. +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
  11361. +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
  11362. +
  11363. +extern u32 ar71xx_ahb_freq;
  11364. +extern u32 ar71xx_cpu_freq;
  11365. +extern u32 ar71xx_ddr_freq;
  11366. +extern u32 ar71xx_ref_freq;
  11367. +
  11368. +enum ar71xx_soc_type {
  11369. + AR71XX_SOC_UNKNOWN,
  11370. + AR71XX_SOC_AR7130,
  11371. + AR71XX_SOC_AR7141,
  11372. + AR71XX_SOC_AR7161,
  11373. + AR71XX_SOC_AR7240,
  11374. + AR71XX_SOC_AR7241,
  11375. + AR71XX_SOC_AR7242,
  11376. + AR71XX_SOC_AR9130,
  11377. + AR71XX_SOC_AR9132,
  11378. + AR71XX_SOC_AR9330,
  11379. + AR71XX_SOC_AR9331,
  11380. + AR71XX_SOC_AR9341,
  11381. + AR71XX_SOC_AR9342,
  11382. + AR71XX_SOC_AR9344,
  11383. +};
  11384. +extern u32 ar71xx_soc_rev;
  11385. +
  11386. +extern enum ar71xx_soc_type ar71xx_soc;
  11387. +
  11388. +/*
  11389. + * PLL block
  11390. + */
  11391. +#define AR71XX_PLL_REG_CPU_CONFIG 0x00
  11392. +#define AR71XX_PLL_REG_SEC_CONFIG 0x04
  11393. +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
  11394. +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
  11395. +
  11396. +#define AR71XX_PLL_DIV_SHIFT 3
  11397. +#define AR71XX_PLL_DIV_MASK 0x1f
  11398. +#define AR71XX_CPU_DIV_SHIFT 16
  11399. +#define AR71XX_CPU_DIV_MASK 0x3
  11400. +#define AR71XX_DDR_DIV_SHIFT 18
  11401. +#define AR71XX_DDR_DIV_MASK 0x3
  11402. +#define AR71XX_AHB_DIV_SHIFT 20
  11403. +#define AR71XX_AHB_DIV_MASK 0x7
  11404. +
  11405. +#define AR71XX_ETH0_PLL_SHIFT 17
  11406. +#define AR71XX_ETH1_PLL_SHIFT 19
  11407. +
  11408. +#define AR724X_PLL_REG_CPU_CONFIG 0x00
  11409. +#define AR724X_PLL_REG_PCIE_CONFIG 0x18
  11410. +
  11411. +#define AR724X_PLL_DIV_SHIFT 0
  11412. +#define AR724X_PLL_DIV_MASK 0x3ff
  11413. +#define AR724X_PLL_REF_DIV_SHIFT 10
  11414. +#define AR724X_PLL_REF_DIV_MASK 0xf
  11415. +#define AR724X_AHB_DIV_SHIFT 19
  11416. +#define AR724X_AHB_DIV_MASK 0x1
  11417. +#define AR724X_DDR_DIV_SHIFT 22
  11418. +#define AR724X_DDR_DIV_MASK 0x3
  11419. +
  11420. +#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c
  11421. +
  11422. +#define AR91XX_PLL_REG_CPU_CONFIG 0x00
  11423. +#define AR91XX_PLL_REG_ETH_CONFIG 0x04
  11424. +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
  11425. +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
  11426. +
  11427. +#define AR91XX_PLL_DIV_SHIFT 0
  11428. +#define AR91XX_PLL_DIV_MASK 0x3ff
  11429. +#define AR91XX_DDR_DIV_SHIFT 22
  11430. +#define AR91XX_DDR_DIV_MASK 0x3
  11431. +#define AR91XX_AHB_DIV_SHIFT 19
  11432. +#define AR91XX_AHB_DIV_MASK 0x1
  11433. +
  11434. +#define AR91XX_ETH0_PLL_SHIFT 20
  11435. +#define AR91XX_ETH1_PLL_SHIFT 22
  11436. +
  11437. +#define AR933X_PLL_CPU_CONFIG_REG 0x00
  11438. +#define AR933X_PLL_CLOCK_CTRL_REG 0x08
  11439. +
  11440. +#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10
  11441. +#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f
  11442. +#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16
  11443. +#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
  11444. +#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23
  11445. +#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
  11446. +
  11447. +#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2)
  11448. +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5
  11449. +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3
  11450. +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10
  11451. +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3
  11452. +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
  11453. +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
  11454. +
  11455. +#define AR934X_PLL_REG_CPU_CONFIG 0x00
  11456. +#define AR934X_PLL_REG_DDR_CTRL_CLOCK 0x8
  11457. +
  11458. +#define AR934X_CPU_PLL_CFG_OUTDIV_MSB 21
  11459. +#define AR934X_CPU_PLL_CFG_OUTDIV_LSB 19
  11460. +#define AR934X_CPU_PLL_CFG_OUTDIV_MASK 0x00380000
  11461. +
  11462. +#define AR934X_CPU_PLL_CFG_OUTDIV_GET(x) \
  11463. + (((x) & AR934X_CPU_PLL_CFG_OUTDIV_MASK) >> \
  11464. + AR934X_CPU_PLL_CFG_OUTDIV_LSB)
  11465. +
  11466. +#define AR934X_DDR_PLL_CFG_OUTDIV_MSB 25
  11467. +#define AR934X_DDR_PLL_CFG_OUTDIV_LSB 23
  11468. +#define AR934X_DDR_PLL_CFG_OUTDIV_MASK 0x03800000
  11469. +
  11470. +#define AR934X_DDR_PLL_CFG_OUTDIV_GET(x) \
  11471. + (((x) & AR934X_DDR_PLL_CFG_OUTDIV_MASK) >> \
  11472. + AR934X_DDR_PLL_CFG_OUTDIV_LSB)
  11473. +
  11474. +#define AR934X_DDR_PLL_CFG_OUTDIV_SET(x) \
  11475. + (((x) << AR934X_DDR_PLL_CFG_OUTDIV_LSB) & \
  11476. + AR934X_DDR_PLL_CFG_OUTDIV_MASK)
  11477. +
  11478. +#define AR934X_CPU_PLL_CFG_REFDIV_MSB 16
  11479. +#define AR934X_CPU_PLL_CFG_REFDIV_LSB 12
  11480. +#define AR934X_CPU_PLL_CFG_REFDIV_MASK 0x0001f000
  11481. +
  11482. +#define AR934X_CPU_PLL_CFG_REFDIV_GET(x) \
  11483. + (((x) & AR934X_CPU_PLL_CFG_REFDIV_MASK) >> \
  11484. + AR934X_CPU_PLL_CFG_REFDIV_LSB)
  11485. +
  11486. +#define AR934X_CPU_PLL_CFG_REFDIV_SET(x) \
  11487. + (((x) << AR934X_CPU_PLL_CFG_REFDIV_LSB) & \
  11488. + AR934X_CPU_PLL_CFG_REFDIV_MASK)
  11489. +
  11490. +#define AR934X_CPU_PLL_CFG_REFDIV_RESET 2
  11491. +
  11492. +#define AR934X_CPU_PLL_CFG_NINT_MSB 11
  11493. +#define AR934X_CPU_PLL_CFG_NINT_LSB 6
  11494. +#define AR934X_CPU_PLL_CFG_NINT_MASK 0x00000fc0
  11495. +
  11496. +#define AR934X_CPU_PLL_CFG_NINT_GET(x) \
  11497. + (((x) & AR934X_CPU_PLL_CFG_NINT_MASK) >> \
  11498. + AR934X_CPU_PLL_CFG_NINT_LSB)
  11499. +
  11500. +#define AR934X_CPU_PLL_CFG_NINT_SET(x) \
  11501. + (((x) << AR934X_CPU_PLL_CFG_NINT_LSB) & \
  11502. + AR934X_CPU_PLL_CFG_NINT_MASK)
  11503. +
  11504. +#define AR934X_CPU_PLL_CFG_NINT_RESET 20
  11505. +
  11506. +#define AR934X_CPU_PLL_CFG_NFRAC_MSB 5
  11507. +#define AR934X_CPU_PLL_CFG_NFRAC_LSB 0
  11508. +#define AR934X_CPU_PLL_CFG_NFRAC_MASK 0x0000003f
  11509. +
  11510. +#define AR934X_CPU_PLL_CFG_NFRAC_GET(x) \
  11511. + (((x) & AR934X_CPU_PLL_CFG_NFRAC_MASK) >> \
  11512. + AR934X_CPU_PLL_CFG_NFRAC_LSB)
  11513. +
  11514. +#define AR934X_CPU_PLL_CFG_NFRAC_SET(x) \
  11515. + (((x) << AR934X_CPU_PLL_CFG_NFRAC_LSB) & \
  11516. + AR934X_CPU_PLL_CFG_NFRAC_MASK)
  11517. +
  11518. +#define AR934X_DDR_PLL_CFG_REFDIV_MSB 20
  11519. +#define AR934X_DDR_PLL_CFG_REFDIV_LSB 16
  11520. +#define AR934X_DDR_PLL_CFG_REFDIV_MASK 0x001f0000
  11521. +
  11522. +#define AR934X_DDR_PLL_CFG_REFDIV_GET(x) \
  11523. + (((x) & AR934X_DDR_PLL_CFG_REFDIV_MASK) >> \
  11524. + AR934X_DDR_PLL_CFG_REFDIV_LSB)
  11525. +
  11526. +#define AR934X_DDR_PLL_CFG_REFDIV_SET(x) \
  11527. + (((x) << AR934X_DDR_PLL_CFG_REFDIV_LSB) & \
  11528. + AR934X_DDR_PLL_CFG_REFDIV_MASK)
  11529. +
  11530. +#define AR934X_DDR_PLL_CFG_REFDIV_RESET 2
  11531. +
  11532. +#define AR934X_DDR_PLL_CFG_NINT_MSB 15
  11533. +#define AR934X_DDR_PLL_CFG_NINT_LSB 10
  11534. +#define AR934X_DDR_PLL_CFG_NINT_MASK 0x0000fc00
  11535. +
  11536. +#define AR934X_DDR_PLL_CFG_NINT_GET(x) \
  11537. + (((x) & AR934X_DDR_PLL_CFG_NINT_MASK) >> \
  11538. + AR934X_DDR_PLL_CFG_NINT_LSB)
  11539. +
  11540. +#define AR934X_DDR_PLL_CFG_NINT_SET(x) \
  11541. + (((x) << AR934X_DDR_PLL_CFG_NINT_LSB) & \
  11542. + AR934X_DDR_PLL_CFG_NINT_MASK)
  11543. +
  11544. +#define AR934X_DDR_PLL_CFG_NINT_RESET 20
  11545. +
  11546. +#define AR934X_DDR_PLL_CFG_NFRAC_MSB 9
  11547. +#define AR934X_DDR_PLL_CFG_NFRAC_LSB 0
  11548. +#define AR934X_DDR_PLL_CFG_NFRAC_MASK 0x000003ff
  11549. +
  11550. +#define AR934X_DDR_PLL_CFG_NFRAC_GET(x) \
  11551. + (((x) & AR934X_DDR_PLL_CFG_NFRAC_MASK) >> \
  11552. + AR934X_DDR_PLL_CFG_NFRAC_LSB)
  11553. +
  11554. +#define AR934X_DDR_PLL_CFG_NFRAC_SET(x) \
  11555. + (((x) << AR934X_DDR_PLL_CFG_NFRAC_LSB) & \
  11556. + AR934X_DDR_PLL_CFG_NFRAC_MASK)
  11557. +
  11558. +#define AR934X_DDR_PLL_CFG_NFRAC_RESET 512
  11559. +
  11560. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MSB 19
  11561. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB 15
  11562. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x000f8000
  11563. +
  11564. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(x) \
  11565. + (((x) & AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) >> \
  11566. + AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB)
  11567. +
  11568. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SET(x) \
  11569. + (((x) << AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) & \
  11570. + AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK)
  11571. +
  11572. +#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_RESET 0
  11573. +
  11574. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MSB 14
  11575. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB 10
  11576. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x00007c00
  11577. +
  11578. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(x) \
  11579. + (((x) & AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) >> \
  11580. + AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB)
  11581. +
  11582. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SET(x) \
  11583. + (((x) << AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) & \
  11584. + AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK)
  11585. +
  11586. +#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_RESET 0
  11587. +
  11588. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MSB 9
  11589. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB 5
  11590. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x000003e0
  11591. +
  11592. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(x) \
  11593. + (((x) & AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) >> \
  11594. + AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB)
  11595. +
  11596. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SET(x) \
  11597. + (((x) << AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) & \
  11598. + AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK)
  11599. +
  11600. +#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_RESET 0
  11601. +
  11602. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MSB 24
  11603. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB 24
  11604. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK 0x01000000
  11605. +
  11606. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(x) \
  11607. + (((x) & AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) >> \
  11608. + AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB)
  11609. +
  11610. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_SET(x) \
  11611. + (((x) << AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) & \
  11612. + AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK)
  11613. +
  11614. +#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_RESET 1
  11615. +
  11616. +extern void __iomem *ar71xx_pll_base;
  11617. +
  11618. +static inline void ar71xx_pll_wr(unsigned reg, u32 val)
  11619. +{
  11620. + __raw_writel(val, ar71xx_pll_base + reg);
  11621. +}
  11622. +
  11623. +static inline u32 ar71xx_pll_rr(unsigned reg)
  11624. +{
  11625. + return __raw_readl(ar71xx_pll_base + reg);
  11626. +}
  11627. +
  11628. +/*
  11629. + * USB_CONFIG block
  11630. + */
  11631. +#define USB_CTRL_REG_FLADJ 0x00
  11632. +#define USB_CTRL_REG_CONFIG 0x04
  11633. +
  11634. +extern void __iomem *ar71xx_usb_ctrl_base;
  11635. +
  11636. +static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
  11637. +{
  11638. + __raw_writel(val, ar71xx_usb_ctrl_base + reg);
  11639. +}
  11640. +
  11641. +static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
  11642. +{
  11643. + return __raw_readl(ar71xx_usb_ctrl_base + reg);
  11644. +}
  11645. +
  11646. +/*
  11647. + * GPIO block
  11648. + */
  11649. +#define GPIO_REG_OE 0x00
  11650. +#define GPIO_REG_IN 0x04
  11651. +#define GPIO_REG_OUT 0x08
  11652. +#define GPIO_REG_SET 0x0c
  11653. +#define GPIO_REG_CLEAR 0x10
  11654. +#define GPIO_REG_INT_MODE 0x14
  11655. +#define GPIO_REG_INT_TYPE 0x18
  11656. +#define GPIO_REG_INT_POLARITY 0x1c
  11657. +#define GPIO_REG_INT_PENDING 0x20
  11658. +#define GPIO_REG_INT_ENABLE 0x24
  11659. +#define GPIO_REG_FUNC 0x28
  11660. +
  11661. +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
  11662. +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
  11663. +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
  11664. +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
  11665. +#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
  11666. +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
  11667. +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
  11668. +
  11669. +#define AR71XX_GPIO_COUNT 16
  11670. +
  11671. +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
  11672. +#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
  11673. +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
  11674. +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
  11675. +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
  11676. +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
  11677. +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
  11678. +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
  11679. +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
  11680. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
  11681. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
  11682. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
  11683. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
  11684. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
  11685. +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
  11686. +#define AR724X_GPIO_FUNC_UART_EN BIT(1)
  11687. +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
  11688. +
  11689. +#define AR724X_GPIO_COUNT 18
  11690. +
  11691. +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
  11692. +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
  11693. +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
  11694. +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
  11695. +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
  11696. +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
  11697. +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
  11698. +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
  11699. +#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
  11700. +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
  11701. +
  11702. +#define AR91XX_GPIO_COUNT 22
  11703. +
  11704. +#define AR933X_GPIO_COUNT 30
  11705. +
  11706. +#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14)
  11707. +#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13)
  11708. +
  11709. +#define AR934X_GPIO_COUNT 32
  11710. +#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17)
  11711. +
  11712. +extern void __iomem *ar71xx_gpio_base;
  11713. +
  11714. +static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
  11715. +{
  11716. + __raw_writel(value, ar71xx_gpio_base + reg);
  11717. +}
  11718. +
  11719. +static inline u32 ar71xx_gpio_rr(unsigned reg)
  11720. +{
  11721. + return __raw_readl(ar71xx_gpio_base + reg);
  11722. +}
  11723. +
  11724. +void ar71xx_gpio_init(void) __init;
  11725. +void ar71xx_gpio_function_enable(u32 mask);
  11726. +void ar71xx_gpio_function_disable(u32 mask);
  11727. +void ar71xx_gpio_function_setup(u32 set, u32 clear);
  11728. +
  11729. +/*
  11730. + * DDR_CTRL block
  11731. + */
  11732. +#define AR71XX_DDR_REG_PCI_WIN0 0x7c
  11733. +#define AR71XX_DDR_REG_PCI_WIN1 0x80
  11734. +#define AR71XX_DDR_REG_PCI_WIN2 0x84
  11735. +#define AR71XX_DDR_REG_PCI_WIN3 0x88
  11736. +#define AR71XX_DDR_REG_PCI_WIN4 0x8c
  11737. +#define AR71XX_DDR_REG_PCI_WIN5 0x90
  11738. +#define AR71XX_DDR_REG_PCI_WIN6 0x94
  11739. +#define AR71XX_DDR_REG_PCI_WIN7 0x98
  11740. +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
  11741. +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
  11742. +#define AR71XX_DDR_REG_FLUSH_USB 0xa4
  11743. +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
  11744. +
  11745. +#define AR724X_DDR_REG_FLUSH_GE0 0x7c
  11746. +#define AR724X_DDR_REG_FLUSH_GE1 0x80
  11747. +#define AR724X_DDR_REG_FLUSH_USB 0x84
  11748. +#define AR724X_DDR_REG_FLUSH_PCIE 0x88
  11749. +
  11750. +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
  11751. +#define AR91XX_DDR_REG_FLUSH_GE1 0x80
  11752. +#define AR91XX_DDR_REG_FLUSH_USB 0x84
  11753. +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
  11754. +
  11755. +#define AR933X_DDR_REG_FLUSH_GE0 0x7c
  11756. +#define AR933X_DDR_REG_FLUSH_GE1 0x80
  11757. +#define AR933X_DDR_REG_FLUSH_USB 0x84
  11758. +#define AR933X_DDR_REG_FLUSH_WMAC 0x88
  11759. +
  11760. +#define AR934X_DDR_REG_FLUSH_GE0 0x9c
  11761. +#define AR934X_DDR_REG_FLUSH_GE1 0xa0
  11762. +#define AR934X_DDR_REG_FLUSH_USB 0xa4
  11763. +#define AR934X_DDR_REG_FLUSH_PCIE 0xa8
  11764. +
  11765. +
  11766. +#define PCI_WIN0_OFFS 0x10000000
  11767. +#define PCI_WIN1_OFFS 0x11000000
  11768. +#define PCI_WIN2_OFFS 0x12000000
  11769. +#define PCI_WIN3_OFFS 0x13000000
  11770. +#define PCI_WIN4_OFFS 0x14000000
  11771. +#define PCI_WIN5_OFFS 0x15000000
  11772. +#define PCI_WIN6_OFFS 0x16000000
  11773. +#define PCI_WIN7_OFFS 0x07000000
  11774. +
  11775. +extern void __iomem *ar71xx_ddr_base;
  11776. +
  11777. +static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
  11778. +{
  11779. + __raw_writel(val, ar71xx_ddr_base + reg);
  11780. +}
  11781. +
  11782. +static inline u32 ar71xx_ddr_rr(unsigned reg)
  11783. +{
  11784. + return __raw_readl(ar71xx_ddr_base + reg);
  11785. +}
  11786. +
  11787. +void ar71xx_ddr_flush(u32 reg);
  11788. +
  11789. +/*
  11790. + * PCI block
  11791. + */
  11792. +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
  11793. +#define AR71XX_PCI_CFG_SIZE 0x100
  11794. +
  11795. +#define PCI_REG_CRP_AD_CBE 0x00
  11796. +#define PCI_REG_CRP_WRDATA 0x04
  11797. +#define PCI_REG_CRP_RDDATA 0x08
  11798. +#define PCI_REG_CFG_AD 0x0c
  11799. +#define PCI_REG_CFG_CBE 0x10
  11800. +#define PCI_REG_CFG_WRDATA 0x14
  11801. +#define PCI_REG_CFG_RDDATA 0x18
  11802. +#define PCI_REG_PCI_ERR 0x1c
  11803. +#define PCI_REG_PCI_ERR_ADDR 0x20
  11804. +#define PCI_REG_AHB_ERR 0x24
  11805. +#define PCI_REG_AHB_ERR_ADDR 0x28
  11806. +
  11807. +#define PCI_CRP_CMD_WRITE 0x00010000
  11808. +#define PCI_CRP_CMD_READ 0x00000000
  11809. +#define PCI_CFG_CMD_READ 0x0000000a
  11810. +#define PCI_CFG_CMD_WRITE 0x0000000b
  11811. +
  11812. +#define PCI_IDSEL_ADL_START 17
  11813. +
  11814. +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
  11815. +#define AR724X_PCI_CFG_SIZE 0x1000
  11816. +
  11817. +#define AR724X_PCI_REG_APP 0x00
  11818. +#define AR724X_PCI_REG_RESET 0x18
  11819. +#define AR724X_PCI_REG_INT_STATUS 0x4c
  11820. +#define AR724X_PCI_REG_INT_MASK 0x50
  11821. +
  11822. +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
  11823. +#define AR724X_PCI_RESET_LINK_UP BIT(0)
  11824. +
  11825. +#define AR724X_PCI_INT_DEV0 BIT(14)
  11826. +
  11827. +/*
  11828. + * RESET block
  11829. + */
  11830. +#define AR71XX_RESET_REG_TIMER 0x00
  11831. +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
  11832. +#define AR71XX_RESET_REG_WDOG_CTRL 0x08
  11833. +#define AR71XX_RESET_REG_WDOG 0x0c
  11834. +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
  11835. +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
  11836. +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
  11837. +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
  11838. +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
  11839. +#define AR71XX_RESET_REG_RESET_MODULE 0x24
  11840. +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
  11841. +#define AR71XX_RESET_REG_PERFC0 0x30
  11842. +#define AR71XX_RESET_REG_PERFC1 0x34
  11843. +#define AR71XX_RESET_REG_REV_ID 0x90
  11844. +
  11845. +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
  11846. +#define AR91XX_RESET_REG_RESET_MODULE 0x1c
  11847. +#define AR91XX_RESET_REG_PERF_CTRL 0x20
  11848. +#define AR91XX_RESET_REG_PERFC0 0x24
  11849. +#define AR91XX_RESET_REG_PERFC1 0x28
  11850. +
  11851. +#define AR724X_RESET_REG_RESET_MODULE 0x1c
  11852. +
  11853. +#define AR933X_RESET_REG_RESET_MODULE 0x1c
  11854. +#define AR933X_RESET_REG_BOOTSTRAP 0xac
  11855. +#define AR933X_BOOTSTRAP_EEPBUSY BIT(4)
  11856. +#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
  11857. +
  11858. +#define AR934X_RESET_REG_RESET_MODULE 0x1c
  11859. +#define AR934X_RESET_REG_BOOTSTRAP 0xb0
  11860. +/* 0 - 25MHz 1 - 40 MHz */
  11861. +#define AR934X_REF_CLK_40 (1 << 4)
  11862. +
  11863. +#define WDOG_CTRL_LAST_RESET BIT(31)
  11864. +#define WDOG_CTRL_ACTION_MASK 3
  11865. +#define WDOG_CTRL_ACTION_NONE 0 /* no action */
  11866. +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
  11867. +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
  11868. +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
  11869. +
  11870. +#define MISC_INT_ENET_LINK BIT(12)
  11871. +#define MISC_INT_DDR_PERF BIT(11)
  11872. +#define MISC_INT_TIMER4 BIT(10)
  11873. +#define MISC_INT_TIMER3 BIT(9)
  11874. +#define MISC_INT_TIMER2 BIT(8)
  11875. +#define MISC_INT_DMA BIT(7)
  11876. +#define MISC_INT_OHCI BIT(6)
  11877. +#define MISC_INT_PERFC BIT(5)
  11878. +#define MISC_INT_WDOG BIT(4)
  11879. +#define MISC_INT_UART BIT(3)
  11880. +#define MISC_INT_GPIO BIT(2)
  11881. +#define MISC_INT_ERROR BIT(1)
  11882. +#define MISC_INT_TIMER BIT(0)
  11883. +
  11884. +#define PCI_INT_CORE BIT(4)
  11885. +#define PCI_INT_DEV2 BIT(2)
  11886. +#define PCI_INT_DEV1 BIT(1)
  11887. +#define PCI_INT_DEV0 BIT(0)
  11888. +
  11889. +#define RESET_MODULE_EXTERNAL BIT(28)
  11890. +#define RESET_MODULE_FULL_CHIP BIT(24)
  11891. +#define RESET_MODULE_AMBA2WMAC BIT(22)
  11892. +#define RESET_MODULE_CPU_NMI BIT(21)
  11893. +#define RESET_MODULE_CPU_COLD BIT(20)
  11894. +#define RESET_MODULE_DMA BIT(19)
  11895. +#define RESET_MODULE_SLIC BIT(18)
  11896. +#define RESET_MODULE_STEREO BIT(17)
  11897. +#define RESET_MODULE_DDR BIT(16)
  11898. +#define RESET_MODULE_GE1_MAC BIT(13)
  11899. +#define RESET_MODULE_GE1_PHY BIT(12)
  11900. +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
  11901. +#define RESET_MODULE_GE0_MAC BIT(9)
  11902. +#define RESET_MODULE_GE0_PHY BIT(8)
  11903. +#define RESET_MODULE_USB_OHCI_DLL BIT(6)
  11904. +#define RESET_MODULE_USB_HOST BIT(5)
  11905. +#define RESET_MODULE_USB_PHY BIT(4)
  11906. +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
  11907. +#define RESET_MODULE_PCI_BUS BIT(1)
  11908. +#define RESET_MODULE_PCI_CORE BIT(0)
  11909. +
  11910. +#define AR724X_RESET_GE1_MDIO BIT(23)
  11911. +#define AR724X_RESET_GE0_MDIO BIT(22)
  11912. +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
  11913. +#define AR724X_RESET_PCIE_PHY BIT(7)
  11914. +#define AR724X_RESET_PCIE BIT(6)
  11915. +#define AR724X_RESET_USB_HOST BIT(5)
  11916. +#define AR724X_RESET_USB_PHY BIT(4)
  11917. +#define AR724X_RESET_USBSUS_OVERRIDE BIT(3)
  11918. +
  11919. +#define AR933X_RESET_WMAC BIT(11)
  11920. +#define AR933X_RESET_GE1_MDIO BIT(23)
  11921. +#define AR933X_RESET_GE0_MDIO BIT(22)
  11922. +#define AR933X_RESET_GE1_MAC BIT(13)
  11923. +#define AR933X_RESET_GE0_MAC BIT(9)
  11924. +
  11925. +#define REV_ID_MAJOR_MASK 0xfff0
  11926. +#define REV_ID_MAJOR_AR71XX 0x00a0
  11927. +#define REV_ID_MAJOR_AR913X 0x00b0
  11928. +#define REV_ID_MAJOR_AR7240 0x00c0
  11929. +#define REV_ID_MAJOR_AR7241 0x0100
  11930. +#define REV_ID_MAJOR_AR7242 0x1100
  11931. +#define REV_ID_MAJOR_AR9330 0x0110
  11932. +#define REV_ID_MAJOR_AR9331 0x1110
  11933. +#define REV_ID_MAJOR_AR9341 0x0120
  11934. +#define REV_ID_MAJOR_AR9342 0x1120
  11935. +#define REV_ID_MAJOR_AR9344 0x2120
  11936. +
  11937. +#define AR71XX_REV_ID_MINOR_MASK 0x3
  11938. +#define AR71XX_REV_ID_MINOR_AR7130 0x0
  11939. +#define AR71XX_REV_ID_MINOR_AR7141 0x1
  11940. +#define AR71XX_REV_ID_MINOR_AR7161 0x2
  11941. +#define AR71XX_REV_ID_REVISION_MASK 0x3
  11942. +#define AR71XX_REV_ID_REVISION_SHIFT 2
  11943. +
  11944. +#define AR91XX_REV_ID_MINOR_MASK 0x3
  11945. +#define AR91XX_REV_ID_MINOR_AR9130 0x0
  11946. +#define AR91XX_REV_ID_MINOR_AR9132 0x1
  11947. +#define AR91XX_REV_ID_REVISION_MASK 0x3
  11948. +#define AR91XX_REV_ID_REVISION_SHIFT 2
  11949. +
  11950. +#define AR724X_REV_ID_REVISION_MASK 0x3
  11951. +
  11952. +#define AR933X_REV_ID_REVISION_MASK 0xf
  11953. +
  11954. +#define AR934X_REV_ID_REVISION_MASK 0xf
  11955. +
  11956. +extern void __iomem *ar71xx_reset_base;
  11957. +
  11958. +static inline void ar71xx_reset_wr(unsigned reg, u32 val)
  11959. +{
  11960. + __raw_writel(val, ar71xx_reset_base + reg);
  11961. +}
  11962. +
  11963. +static inline u32 ar71xx_reset_rr(unsigned reg)
  11964. +{
  11965. + return __raw_readl(ar71xx_reset_base + reg);
  11966. +}
  11967. +
  11968. +void ar71xx_device_stop(u32 mask);
  11969. +void ar71xx_device_start(u32 mask);
  11970. +int ar71xx_device_stopped(u32 mask);
  11971. +
  11972. +/*
  11973. + * SPI block
  11974. + */
  11975. +#define SPI_REG_FS 0x00 /* Function Select */
  11976. +#define SPI_REG_CTRL 0x04 /* SPI Control */
  11977. +#define SPI_REG_IOC 0x08 /* SPI I/O Control */
  11978. +#define SPI_REG_RDS 0x0c /* Read Data Shift */
  11979. +
  11980. +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
  11981. +
  11982. +#define SPI_CTRL_RD BIT(6) /* Remap Disable */
  11983. +#define SPI_CTRL_DIV_MASK 0x3f
  11984. +
  11985. +#define SPI_IOC_DO BIT(0) /* Data Out pin */
  11986. +#define SPI_IOC_CLK BIT(8) /* CLK pin */
  11987. +#define SPI_IOC_CS(n) BIT(16 + (n))
  11988. +#define SPI_IOC_CS0 SPI_IOC_CS(0)
  11989. +#define SPI_IOC_CS1 SPI_IOC_CS(1)
  11990. +#define SPI_IOC_CS2 SPI_IOC_CS(2)
  11991. +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
  11992. +
  11993. +void ar71xx_flash_acquire(void);
  11994. +void ar71xx_flash_release(void);
  11995. +
  11996. +/*
  11997. + * MII_CTRL block
  11998. + */
  11999. +#define MII_REG_MII0_CTRL 0x00
  12000. +#define MII_REG_MII1_CTRL 0x04
  12001. +
  12002. +#define MII0_CTRL_IF_GMII 0
  12003. +#define MII0_CTRL_IF_MII 1
  12004. +#define MII0_CTRL_IF_RGMII 2
  12005. +#define MII0_CTRL_IF_RMII 3
  12006. +
  12007. +#define MII1_CTRL_IF_RGMII 0
  12008. +#define MII1_CTRL_IF_RMII 1
  12009. +
  12010. +#endif /* __ASSEMBLER__ */
  12011. +
  12012. +#endif /* __ASM_MACH_AR71XX_H */
  12013. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h
  12014. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100
  12015. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-08-24 18:17:23.000000000 +0200
  12016. @@ -0,0 +1,26 @@
  12017. +/*
  12018. + * AR91xx parallel flash driver platform data definitions
  12019. + *
  12020. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  12021. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12022. + *
  12023. + * This program is free software; you can redistribute it and/or modify it
  12024. + * under the terms of the GNU General Public License version 2 as published
  12025. + * by the Free Software Foundation.
  12026. + */
  12027. +
  12028. +#ifndef __AR91XX_FLASH_H
  12029. +#define __AR91XX_FLASH_H
  12030. +
  12031. +struct mtd_partition;
  12032. +
  12033. +struct ar91xx_flash_platform_data {
  12034. + unsigned int width;
  12035. + u8 is_shared:1;
  12036. +#ifdef CONFIG_MTD_PARTITIONS
  12037. + unsigned int nr_parts;
  12038. + struct mtd_partition *parts;
  12039. +#endif
  12040. +};
  12041. +
  12042. +#endif /* __AR91XX_FLASH_H */
  12043. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h
  12044. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 1970-01-01 01:00:00.000000000 +0100
  12045. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 2011-08-24 18:17:23.000000000 +0200
  12046. @@ -0,0 +1,67 @@
  12047. +/*
  12048. + * Atheros AR933X UART defines
  12049. + *
  12050. + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
  12051. + *
  12052. + * This program is free software; you can redistribute it and/or modify it
  12053. + * under the terms of the GNU General Public License version 2 as published
  12054. + * by the Free Software Foundation.
  12055. + */
  12056. +
  12057. +#ifndef __AR933X_UART_H
  12058. +#define __AR933X_UART_H
  12059. +
  12060. +#define AR933X_UART_REGS_SIZE 20
  12061. +#define AR933X_UART_FIFO_SIZE 16
  12062. +
  12063. +#define AR933X_UART_DATA_REG 0x00
  12064. +#define AR933X_UART_CS_REG 0x04
  12065. +#define AR933X_UART_CLOCK_REG 0x08
  12066. +#define AR933X_UART_INT_REG 0x0c
  12067. +#define AR933X_UART_INT_EN_REG 0x10
  12068. +
  12069. +#define AR933X_UART_DATA_TX_RX_MASK 0xff
  12070. +#define AR933X_UART_DATA_RX_CSR BIT(8)
  12071. +#define AR933X_UART_DATA_TX_CSR BIT(9)
  12072. +
  12073. +#define AR933X_UART_CS_PARITY_S 0
  12074. +#define AR933X_UART_CS_PARITY_M 0x3
  12075. +#define AR933X_UART_CS_PARITY_NONE 0
  12076. +#define AR933X_UART_CS_PARITY_ODD 1
  12077. +#define AR933X_UART_CS_PARITY_EVEN 2
  12078. +#define AR933X_UART_CS_IF_MODE_S 2
  12079. +#define AR933X_UART_CS_IF_MODE_M 0x3
  12080. +#define AR933X_UART_CS_IF_MODE_NONE 0
  12081. +#define AR933X_UART_CS_IF_MODE_DTE 1
  12082. +#define AR933X_UART_CS_IF_MODE_DCE 2
  12083. +#define AR933X_UART_CS_FLOW_CTRL_S 4
  12084. +#define AR933X_UART_CS_FLOW_CTRL_M 0x3
  12085. +#define AR933X_UART_CS_DMA_EN BIT(6)
  12086. +#define AR933X_UART_CS_TX_READY_ORIDE BIT(7)
  12087. +#define AR933X_UART_CS_RX_READY_ORIDE BIT(8)
  12088. +#define AR933X_UART_CS_TX_READY BIT(9)
  12089. +#define AR933X_UART_CS_RX_BREAK BIT(10)
  12090. +#define AR933X_UART_CS_TX_BREAK BIT(11)
  12091. +#define AR933X_UART_CS_HOST_INT BIT(12)
  12092. +#define AR933X_UART_CS_HOST_INT_EN BIT(13)
  12093. +#define AR933X_UART_CS_TX_BUSY BIT(14)
  12094. +#define AR933X_UART_CS_RX_BUSY BIT(15)
  12095. +
  12096. +#define AR933X_UART_CLOCK_STEP_M 0xffff
  12097. +#define AR933X_UART_CLOCK_SCALE_M 0xfff
  12098. +#define AR933X_UART_CLOCK_SCALE_S 16
  12099. +#define AR933X_UART_CLOCK_STEP_M 0xffff
  12100. +
  12101. +#define AR933X_UART_INT_RX_VALID BIT(0)
  12102. +#define AR933X_UART_INT_TX_READY BIT(1)
  12103. +#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2)
  12104. +#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3)
  12105. +#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4)
  12106. +#define AR933X_UART_INT_RX_PARITY_ERR BIT(5)
  12107. +#define AR933X_UART_INT_RX_BREAK_ON BIT(6)
  12108. +#define AR933X_UART_INT_RX_BREAK_OFF BIT(7)
  12109. +#define AR933X_UART_INT_RX_FULL BIT(8)
  12110. +#define AR933X_UART_INT_TX_EMPTY BIT(9)
  12111. +#define AR933X_UART_INT_ALLINTS 0x3ff
  12112. +
  12113. +#endif /* __AR933X_UART_H */
  12114. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h
  12115. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 1970-01-01 01:00:00.000000000 +0100
  12116. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 2011-08-24 18:17:23.000000000 +0200
  12117. @@ -0,0 +1,18 @@
  12118. +/*
  12119. + * Platform data definition for Atheros AR933X UART
  12120. + *
  12121. + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
  12122. + *
  12123. + * This program is free software; you can redistribute it and/or modify it
  12124. + * under the terms of the GNU General Public License version 2 as published
  12125. + * by the Free Software Foundation.
  12126. + */
  12127. +
  12128. +#ifndef _AR933X_UART_PLATFORM_H
  12129. +#define _AR933X_UART_PLATFORM_H
  12130. +
  12131. +struct ar933x_uart_platform_data {
  12132. + unsigned uartclk;
  12133. +};
  12134. +
  12135. +#endif /* _AR933X_UART_PLATFORM_H */
  12136. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h
  12137. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100
  12138. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-08-24 18:17:23.000000000 +0200
  12139. @@ -0,0 +1,56 @@
  12140. +/*
  12141. + * Atheros AR71xx specific CPU feature overrides
  12142. + *
  12143. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  12144. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12145. + *
  12146. + * This file was derived from: include/asm-mips/cpu-features.h
  12147. + * Copyright (C) 2003, 2004 Ralf Baechle
  12148. + * Copyright (C) 2004 Maciej W. Rozycki
  12149. + *
  12150. + * This program is free software; you can redistribute it and/or modify it
  12151. + * under the terms of the GNU General Public License version 2 as published
  12152. + * by the Free Software Foundation.
  12153. + *
  12154. + */
  12155. +#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  12156. +#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  12157. +
  12158. +#define cpu_has_tlb 1
  12159. +#define cpu_has_4kex 1
  12160. +#define cpu_has_3k_cache 0
  12161. +#define cpu_has_4k_cache 1
  12162. +#define cpu_has_tx39_cache 0
  12163. +#define cpu_has_sb1_cache 0
  12164. +#define cpu_has_fpu 0
  12165. +#define cpu_has_32fpr 0
  12166. +#define cpu_has_counter 1
  12167. +#define cpu_has_watch 1
  12168. +#define cpu_has_divec 1
  12169. +
  12170. +#define cpu_has_prefetch 1
  12171. +#define cpu_has_ejtag 1
  12172. +#define cpu_has_llsc 1
  12173. +
  12174. +#define cpu_has_mips16 1
  12175. +#define cpu_has_mdmx 0
  12176. +#define cpu_has_mips3d 0
  12177. +#define cpu_has_smartmips 0
  12178. +
  12179. +#define cpu_has_mips32r1 1
  12180. +#define cpu_has_mips32r2 1
  12181. +#define cpu_has_mips64r1 0
  12182. +#define cpu_has_mips64r2 0
  12183. +
  12184. +#define cpu_has_dsp 0
  12185. +#define cpu_has_mipsmt 0
  12186. +
  12187. +#define cpu_has_64bits 0
  12188. +#define cpu_has_64bit_zero_reg 0
  12189. +#define cpu_has_64bit_gp_regs 0
  12190. +#define cpu_has_64bit_addresses 0
  12191. +
  12192. +#define cpu_dcache_line_size() 32
  12193. +#define cpu_icache_line_size() 32
  12194. +
  12195. +#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */
  12196. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h
  12197. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100
  12198. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-08-24 18:17:23.000000000 +0200
  12199. @@ -0,0 +1,53 @@
  12200. +/*
  12201. + * Atheros AR71xx GPIO API definitions
  12202. + *
  12203. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  12204. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12205. + *
  12206. + * This program is free software; you can redistribute it and/or modify it
  12207. + * under the terms of the GNU General Public License version 2 as published
  12208. + * by the Free Software Foundation.
  12209. + *
  12210. + */
  12211. +
  12212. +#ifndef __ASM_MACH_AR71XX_GPIO_H
  12213. +#define __ASM_MACH_AR71XX_GPIO_H
  12214. +
  12215. +#define ARCH_NR_GPIOS 64
  12216. +#include <asm-generic/gpio.h>
  12217. +
  12218. +#include <asm/mach-ar71xx/ar71xx.h>
  12219. +
  12220. +extern unsigned long ar71xx_gpio_count;
  12221. +extern void __ar71xx_gpio_set_value(unsigned gpio, int value);
  12222. +extern int __ar71xx_gpio_get_value(unsigned gpio);
  12223. +
  12224. +static inline int gpio_to_irq(unsigned gpio)
  12225. +{
  12226. + return AR71XX_GPIO_IRQ(gpio);
  12227. +}
  12228. +
  12229. +static inline int irq_to_gpio(unsigned irq)
  12230. +{
  12231. + return irq - AR71XX_GPIO_IRQ_BASE;
  12232. +}
  12233. +
  12234. +static inline int gpio_get_value(unsigned gpio)
  12235. +{
  12236. + if (gpio < ar71xx_gpio_count)
  12237. + return __ar71xx_gpio_get_value(gpio);
  12238. +
  12239. + return __gpio_get_value(gpio);
  12240. +}
  12241. +
  12242. +static inline void gpio_set_value(unsigned gpio, int value)
  12243. +{
  12244. + if (gpio < ar71xx_gpio_count)
  12245. + __ar71xx_gpio_set_value(gpio, value);
  12246. + else
  12247. + __gpio_set_value(gpio, value);
  12248. +}
  12249. +
  12250. +#define gpio_cansleep __gpio_cansleep
  12251. +
  12252. +#endif /* __ASM_MACH_AR71XX_GPIO_H */
  12253. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h
  12254. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100
  12255. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-08-24 18:17:23.000000000 +0200
  12256. @@ -0,0 +1,17 @@
  12257. +/*
  12258. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  12259. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12260. + *
  12261. + * This program is free software; you can redistribute it and/or modify it
  12262. + * under the terms of the GNU General Public License version 2 as published
  12263. + * by the Free Software Foundation.
  12264. + */
  12265. +#ifndef __ASM_MACH_AR71XX_IRQ_H
  12266. +#define __ASM_MACH_AR71XX_IRQ_H
  12267. +
  12268. +#define MIPS_CPU_IRQ_BASE 0
  12269. +#define NR_IRQS 80
  12270. +
  12271. +#include_next <irq.h>
  12272. +
  12273. +#endif /* __ASM_MACH_AR71XX_IRQ_H */
  12274. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h
  12275. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
  12276. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-08-24 18:17:23.000000000 +0200
  12277. @@ -0,0 +1,32 @@
  12278. +/*
  12279. + * Atheros AR71xx specific kernel entry setup
  12280. + *
  12281. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  12282. + *
  12283. + * This program is free software; you can redistribute it and/or modify it
  12284. + * under the terms of the GNU General Public License version 2 as published
  12285. + * by the Free Software Foundation.
  12286. + *
  12287. + */
  12288. +#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  12289. +#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  12290. +
  12291. + /*
  12292. + * Some bootloaders set the 'Kseg0 coherency algorithm' to
  12293. + * 'Cacheable, noncoherent, write-through, no write allocate'
  12294. + * and this cause performance issues. Let's go and change it to
  12295. + * 'Cacheable, noncoherent, write-back, write allocate'
  12296. + */
  12297. + .macro kernel_entry_setup
  12298. + mfc0 t0, CP0_CONFIG
  12299. + li t1, ~CONF_CM_CMASK
  12300. + and t0, t1
  12301. + ori t0, CONF_CM_CACHABLE_NONCOHERENT
  12302. + mtc0 t0, CP0_CONFIG
  12303. + nop
  12304. + .endm
  12305. +
  12306. + .macro smp_slave_setup
  12307. + .endm
  12308. +
  12309. +#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */
  12310. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h
  12311. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100
  12312. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-08-24 18:17:23.000000000 +0200
  12313. @@ -0,0 +1,66 @@
  12314. +/*
  12315. + * MikroTik RouterBOARD 750 definitions
  12316. + *
  12317. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  12318. + *
  12319. + * This program is free software; you can redistribute it and/or modify it
  12320. + * under the terms of the GNU General Public License version 2 as published
  12321. + * by the Free Software Foundation.
  12322. + */
  12323. +#ifndef _MACH_RB750_H
  12324. +#define _MACH_RB750_H
  12325. +
  12326. +#include <linux/bitops.h>
  12327. +
  12328. +#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */
  12329. +#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */
  12330. +#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */
  12331. +#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */
  12332. +#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */
  12333. +#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */
  12334. +#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */
  12335. +#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */
  12336. +#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */
  12337. +#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */
  12338. +#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */
  12339. +#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */
  12340. +#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */
  12341. +#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */
  12342. +#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */
  12343. +
  12344. +#define RB750_GPIO_BTN_RESET 1
  12345. +#define RB750_GPIO_SPI_CS0 2
  12346. +#define RB750_GPIO_LED_ACT 12
  12347. +#define RB750_GPIO_LED_PORT1 13
  12348. +#define RB750_GPIO_LED_PORT2 14
  12349. +#define RB750_GPIO_LED_PORT3 15
  12350. +#define RB750_GPIO_LED_PORT4 16
  12351. +#define RB750_GPIO_LED_PORT5 17
  12352. +
  12353. +#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT)
  12354. +#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1)
  12355. +#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2)
  12356. +#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3)
  12357. +#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4)
  12358. +#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5)
  12359. +
  12360. +#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE)
  12361. +
  12362. +#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \
  12363. + RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT)
  12364. +
  12365. +struct rb750_led_data {
  12366. + char *name;
  12367. + char *default_trigger;
  12368. + u32 mask;
  12369. + int active_low;
  12370. +};
  12371. +
  12372. +struct rb750_led_platform_data {
  12373. + int num_leds;
  12374. + struct rb750_led_data *leds;
  12375. +};
  12376. +
  12377. +int rb750_latch_change(u32 mask_clr, u32 mask_set);
  12378. +
  12379. +#endif /* _MACH_RB750_H */
  12380. \ No newline at end of file
  12381. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h
  12382. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100
  12383. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-08-24 18:17:23.000000000 +0200
  12384. @@ -0,0 +1,45 @@
  12385. +/*
  12386. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  12387. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12388. + *
  12389. + * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
  12390. + * Copyright (C) 2003, 2004 Ralf Baechle
  12391. + *
  12392. + * This program is free software; you can redistribute it and/or modify it
  12393. + * under the terms of the GNU General Public License version 2 as published
  12394. + * by the Free Software Foundation.
  12395. + */
  12396. +
  12397. +#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H
  12398. +#define __ASM_MACH_AR71XX_MANGLE_PORT_H
  12399. +
  12400. +#define __swizzle_addr_b(port) ((port) ^ 3)
  12401. +#define __swizzle_addr_w(port) ((port) ^ 2)
  12402. +#define __swizzle_addr_l(port) (port)
  12403. +#define __swizzle_addr_q(port) (port)
  12404. +
  12405. +#if defined(CONFIG_SWAP_IO_SPACE)
  12406. +
  12407. +# define ioswabb(a, x) (x)
  12408. +# define __mem_ioswabb(a, x) (x)
  12409. +# define ioswabw(a, x) le16_to_cpu(x)
  12410. +# define __mem_ioswabw(a, x) (x)
  12411. +# define ioswabl(a, x) le32_to_cpu(x)
  12412. +# define __mem_ioswabl(a, x) (x)
  12413. +# define ioswabq(a, x) le64_to_cpu(x)
  12414. +# define __mem_ioswabq(a, x) (x)
  12415. +
  12416. +#else
  12417. +
  12418. +# define ioswabb(a, x) (x)
  12419. +# define __mem_ioswabb(a, x) (x)
  12420. +# define ioswabw(a, x) (x)
  12421. +# define __mem_ioswabw(a, x) cpu_to_le16(x)
  12422. +# define ioswabl(a, x) (x)
  12423. +# define __mem_ioswabl(a, x) cpu_to_le32(x)
  12424. +# define ioswabq(a, x) (x)
  12425. +# define __mem_ioswabq(a, x) cpu_to_le64(x)
  12426. +
  12427. +#endif
  12428. +
  12429. +#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */
  12430. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h
  12431. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100
  12432. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-08-24 18:17:23.000000000 +0200
  12433. @@ -0,0 +1,46 @@
  12434. +/*
  12435. + * Atheros AR71xx SoC specific PCI definitions
  12436. + *
  12437. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  12438. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12439. + *
  12440. + * This program is free software; you can redistribute it and/or modify it
  12441. + * under the terms of the GNU General Public License version 2 as published
  12442. + * by the Free Software Foundation.
  12443. + */
  12444. +
  12445. +#ifndef __ASM_MACH_AR71XX_PCI_H
  12446. +#define __ASM_MACH_AR71XX_PCI_H
  12447. +
  12448. +struct pci_dev;
  12449. +
  12450. +struct ar71xx_pci_irq {
  12451. + int irq;
  12452. + u8 slot;
  12453. + u8 pin;
  12454. +};
  12455. +
  12456. +#ifdef CONFIG_PCI
  12457. +extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  12458. +extern unsigned ar71xx_pci_nr_irqs __initdata;
  12459. +extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  12460. +
  12461. +int ar71xx_pcibios_map_irq(const struct pci_dev *dev,
  12462. + uint8_t slot, uint8_t pin) __init;
  12463. +int ar71xx_pcibios_init(void) __init;
  12464. +
  12465. +int ar71xx_pci_be_handler(int is_fixup);
  12466. +
  12467. +int ar724x_pcibios_map_irq(const struct pci_dev *dev,
  12468. + uint8_t slot, uint8_t pin) __init;
  12469. +int ar724x_pcibios_init(void) __init;
  12470. +
  12471. +int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init;
  12472. +#else
  12473. +static inline int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  12474. +{
  12475. + return 0;
  12476. +}
  12477. +#endif
  12478. +
  12479. +#endif /* __ASM_MACH_AR71XX_PCI_H */
  12480. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h
  12481. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100
  12482. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-08-24 18:17:23.000000000 +0200
  12483. @@ -0,0 +1,63 @@
  12484. +/*
  12485. + * Atheros AR71xx SoC specific platform data definitions
  12486. + *
  12487. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  12488. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12489. + *
  12490. + * This program is free software; you can redistribute it and/or modify it
  12491. + * under the terms of the GNU General Public License version 2 as published
  12492. + * by the Free Software Foundation.
  12493. + */
  12494. +
  12495. +#ifndef __ASM_MACH_AR71XX_PLATFORM_H
  12496. +#define __ASM_MACH_AR71XX_PLATFORM_H
  12497. +
  12498. +#include <linux/if_ether.h>
  12499. +#include <linux/skbuff.h>
  12500. +#include <linux/phy.h>
  12501. +#include <linux/spi/spi.h>
  12502. +
  12503. +struct ag71xx_platform_data {
  12504. + phy_interface_t phy_if_mode;
  12505. + u32 phy_mask;
  12506. + int speed;
  12507. + int duplex;
  12508. + u32 reset_bit;
  12509. + u32 mii_if;
  12510. + u8 mac_addr[ETH_ALEN];
  12511. + struct device *mii_bus_dev;
  12512. +
  12513. + u8 has_gbit:1;
  12514. + u8 is_ar91xx:1;
  12515. + u8 is_ar7240:1;
  12516. + u8 is_ar724x:1;
  12517. + u8 has_ar8216:1;
  12518. + u8 has_ar7240_switch:1;
  12519. +
  12520. + void (*ddr_flush)(void);
  12521. + void (*set_pll)(int speed);
  12522. +
  12523. + u32 fifo_cfg1;
  12524. + u32 fifo_cfg2;
  12525. + u32 fifo_cfg3;
  12526. +};
  12527. +
  12528. +struct ag71xx_mdio_platform_data {
  12529. + u32 phy_mask;
  12530. + int is_ar7240;
  12531. +};
  12532. +
  12533. +struct ar71xx_ehci_platform_data {
  12534. + u8 is_ar91xx;
  12535. +};
  12536. +
  12537. +struct ar71xx_spi_platform_data {
  12538. + unsigned bus_num;
  12539. + unsigned num_chipselect;
  12540. + u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on);
  12541. +};
  12542. +
  12543. +#define AR71XX_SPI_CS_INACTIVE 0
  12544. +#define AR71XX_SPI_CS_ACTIVE 1
  12545. +
  12546. +#endif /* __ASM_MACH_AR71XX_PLATFORM_H */
  12547. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h
  12548. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 1970-01-01 01:00:00.000000000 +0100
  12549. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 2011-08-24 18:17:24.000000000 +0200
  12550. @@ -0,0 +1,48 @@
  12551. +/*
  12552. + * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards
  12553. + *
  12554. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  12555. + *
  12556. + * This file was based on the patches for Linux 2.6.27.39 published by
  12557. + * MikroTik for their RouterBoard 4xx series devices.
  12558. + *
  12559. + * This program is free software; you can redistribute it and/or modify it
  12560. + * under the terms of the GNU General Public License version 2 as published
  12561. + * by the Free Software Foundation.
  12562. + */
  12563. +
  12564. +#define CPLD_GPIO_nLED1 0
  12565. +#define CPLD_GPIO_nLED2 1
  12566. +#define CPLD_GPIO_nLED3 2
  12567. +#define CPLD_GPIO_nLED4 3
  12568. +#define CPLD_GPIO_FAN 4
  12569. +#define CPLD_GPIO_ALE 5
  12570. +#define CPLD_GPIO_CLE 6
  12571. +#define CPLD_GPIO_nCE 7
  12572. +#define CPLD_GPIO_nLED5 8
  12573. +
  12574. +#define CPLD_NUM_GPIOS 9
  12575. +
  12576. +#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1)
  12577. +#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2)
  12578. +#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3)
  12579. +#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4)
  12580. +#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN)
  12581. +#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE)
  12582. +#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE)
  12583. +#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE)
  12584. +#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5)
  12585. +
  12586. +struct rb4xx_cpld_platform_data {
  12587. + unsigned gpio_base;
  12588. +};
  12589. +
  12590. +extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value);
  12591. +extern int rb4xx_cpld_read(unsigned char *rx_buf,
  12592. + const unsigned char *verify_buf,
  12593. + unsigned cnt);
  12594. +extern int rb4xx_cpld_read_from(unsigned addr,
  12595. + unsigned char *rx_buf,
  12596. + const unsigned char *verify_buf,
  12597. + unsigned cnt);
  12598. +extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count);
  12599. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h
  12600. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100
  12601. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-08-24 18:17:24.000000000 +0200
  12602. @@ -0,0 +1,25 @@
  12603. +/*
  12604. + * This file is subject to the terms and conditions of the GNU General Public
  12605. + * License. See the file "COPYING" in the main directory of this archive
  12606. + * for more details.
  12607. + *
  12608. + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  12609. + */
  12610. +#ifndef __ASM_MACH_AR71XX_WAR_H
  12611. +#define __ASM_MACH_AR71XX_WAR_H
  12612. +
  12613. +#define R4600_V1_INDEX_ICACHEOP_WAR 0
  12614. +#define R4600_V1_HIT_CACHEOP_WAR 0
  12615. +#define R4600_V2_HIT_CACHEOP_WAR 0
  12616. +#define R5432_CP0_INTERRUPT_WAR 0
  12617. +#define BCM1250_M3_WAR 0
  12618. +#define SIBYTE_1956_WAR 0
  12619. +#define MIPS4K_ICACHE_REFILL_WAR 0
  12620. +#define MIPS_CACHE_SYNC_WAR 0
  12621. +#define TX49XX_ICACHE_INDEX_INV_WAR 0
  12622. +#define RM9000_CDEX_SMP_WAR 0
  12623. +#define ICACHE_REFILLS_WORKAROUND_WAR 0
  12624. +#define R10000_LLSC_WAR 0
  12625. +#define MIPS34K_MISSED_ITLB_WAR 0
  12626. +
  12627. +#endif /* __ASM_MACH_AR71XX_WAR_H */
  12628. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h
  12629. --- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200
  12630. +++ linux-2.6.39/arch/mips/include/asm/time.h 2011-08-24 18:17:24.000000000 +0200
  12631. @@ -52,6 +52,7 @@
  12632. */
  12633. #ifdef CONFIG_CEVT_R4K_LIB
  12634. extern unsigned int __weak get_c0_compare_int(void);
  12635. +extern unsigned int __weak get_c0_compare_irq(void);
  12636. extern int r4k_clockevent_init(void);
  12637. #endif
  12638. diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c
  12639. --- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200
  12640. +++ linux-2.6.39/arch/mips/kernel/traps.c 2011-08-24 18:17:24.000000000 +0200
  12641. @@ -54,6 +54,7 @@
  12642. #include <asm/types.h>
  12643. #include <asm/stacktrace.h>
  12644. #include <asm/uasm.h>
  12645. +#include <asm/time.h>
  12646. extern void check_wait(void);
  12647. extern asmlinkage void r4k_wait(void);
  12648. @@ -1576,6 +1577,8 @@
  12649. if (cpu_has_mips_r2) {
  12650. cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
  12651. cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
  12652. + if (get_c0_compare_irq)
  12653. + cp0_compare_irq = get_c0_compare_irq();
  12654. cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
  12655. if (cp0_perfcount_irq == cp0_compare_irq)
  12656. cp0_perfcount_irq = -1;
  12657. diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile
  12658. --- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200
  12659. +++ linux-2.6.39/arch/mips/pci/Makefile 2011-08-24 18:17:24.000000000 +0200
  12660. @@ -18,6 +18,7 @@
  12661. obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
  12662. obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
  12663. ops-bcm63xx.o
  12664. +obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o
  12665. #
  12666. # These are still pretty much in the old state, watch, go blind.
  12667. diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c
  12668. --- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  12669. +++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200
  12670. @@ -0,0 +1,415 @@
  12671. +/*
  12672. + * Atheros AR71xx PCI host controller driver
  12673. + *
  12674. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12675. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12676. + *
  12677. + * Parts of this file are based on Atheros' 2.6.15 BSP
  12678. + *
  12679. + * This program is free software; you can redistribute it and/or modify it
  12680. + * under the terms of the GNU General Public License version 2 as published
  12681. + * by the Free Software Foundation.
  12682. + */
  12683. +
  12684. +#include <linux/resource.h>
  12685. +#include <linux/types.h>
  12686. +#include <linux/delay.h>
  12687. +#include <linux/bitops.h>
  12688. +#include <linux/pci.h>
  12689. +#include <linux/pci_regs.h>
  12690. +#include <linux/interrupt.h>
  12691. +
  12692. +#include <asm/mach-ar71xx/ar71xx.h>
  12693. +#include <asm/mach-ar71xx/pci.h>
  12694. +
  12695. +#undef DEBUG
  12696. +#ifdef DEBUG
  12697. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  12698. +#else
  12699. +#define DBG(fmt, args...)
  12700. +#endif
  12701. +
  12702. +#define AR71XX_PCI_DELAY 100 /* msecs */
  12703. +
  12704. +#if 0
  12705. +#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START
  12706. +#else
  12707. +#define PCI_IDSEL_BASE 0
  12708. +#endif
  12709. +
  12710. +static void __iomem *ar71xx_pcicfg_base;
  12711. +static DEFINE_SPINLOCK(ar71xx_pci_lock);
  12712. +static int ar71xx_pci_fixup_enable;
  12713. +
  12714. +static inline void ar71xx_pci_delay(void)
  12715. +{
  12716. + mdelay(AR71XX_PCI_DELAY);
  12717. +}
  12718. +
  12719. +/* Byte lane enable bits */
  12720. +static u8 ble_table[4][4] = {
  12721. + {0x0, 0xf, 0xf, 0xf},
  12722. + {0xe, 0xd, 0xb, 0x7},
  12723. + {0xc, 0xf, 0x3, 0xf},
  12724. + {0xf, 0xf, 0xf, 0xf},
  12725. +};
  12726. +
  12727. +static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
  12728. +{
  12729. + u32 t;
  12730. +
  12731. + t = ble_table[size & 3][where & 3];
  12732. + BUG_ON(t == 0xf);
  12733. + t <<= (local) ? 20 : 4;
  12734. + return t;
  12735. +}
  12736. +
  12737. +static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
  12738. + int where)
  12739. +{
  12740. + u32 ret;
  12741. +
  12742. + if (!bus->number) {
  12743. + /* type 0 */
  12744. + ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn)))
  12745. + | (PCI_FUNC(devfn) << 8) | (where & ~3);
  12746. + } else {
  12747. + /* type 1 */
  12748. + ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11)
  12749. + | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
  12750. + }
  12751. +
  12752. + return ret;
  12753. +}
  12754. +
  12755. +int ar71xx_pci_be_handler(int is_fixup)
  12756. +{
  12757. + void __iomem *base = ar71xx_pcicfg_base;
  12758. + u32 pci_err;
  12759. + u32 ahb_err;
  12760. +
  12761. + pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3;
  12762. + if (pci_err) {
  12763. + if (!is_fixup)
  12764. + printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n",
  12765. + pci_err,
  12766. + __raw_readl(base + PCI_REG_PCI_ERR_ADDR));
  12767. +
  12768. + __raw_writel(pci_err, base + PCI_REG_PCI_ERR);
  12769. + }
  12770. +
  12771. + ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1;
  12772. + if (ahb_err) {
  12773. + if (!is_fixup)
  12774. + printk(KERN_ALERT "AHB error at AHB address 0x%x\n",
  12775. + __raw_readl(base + PCI_REG_AHB_ERR_ADDR));
  12776. +
  12777. + __raw_writel(ahb_err, base + PCI_REG_AHB_ERR);
  12778. + }
  12779. +
  12780. + return (ahb_err | pci_err) ? 1 : 0;
  12781. +}
  12782. +
  12783. +static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
  12784. + unsigned int devfn, int where, int size, u32 cmd)
  12785. +{
  12786. + void __iomem *base = ar71xx_pcicfg_base;
  12787. + u32 addr;
  12788. +
  12789. + addr = ar71xx_pci_bus_addr(bus, devfn, where);
  12790. +
  12791. + DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n",
  12792. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  12793. + where, size, addr);
  12794. +
  12795. + __raw_writel(addr, base + PCI_REG_CFG_AD);
  12796. + __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
  12797. + base + PCI_REG_CFG_CBE);
  12798. +
  12799. + return ar71xx_pci_be_handler(1);
  12800. +}
  12801. +
  12802. +static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  12803. + int where, int size, u32 *value)
  12804. +{
  12805. + void __iomem *base = ar71xx_pcicfg_base;
  12806. + static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
  12807. + unsigned long flags;
  12808. + u32 data;
  12809. + int retry = 0;
  12810. + int ret;
  12811. +
  12812. + ret = PCIBIOS_SUCCESSFUL;
  12813. +
  12814. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number,
  12815. + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
  12816. +
  12817. +retry:
  12818. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  12819. +
  12820. + if (bus->number == 0 && devfn == 0) {
  12821. + u32 t;
  12822. +
  12823. + t = PCI_CRP_CMD_READ | (where & ~3);
  12824. +
  12825. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  12826. + data = __raw_readl(base + PCI_REG_CRP_RDDATA);
  12827. +
  12828. + DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data);
  12829. +
  12830. + } else {
  12831. + int err;
  12832. +
  12833. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  12834. + PCI_CFG_CMD_READ);
  12835. +
  12836. + if (err == 0) {
  12837. + data = __raw_readl(base + PCI_REG_CFG_RDDATA);
  12838. + } else {
  12839. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  12840. + data = ~0;
  12841. + }
  12842. + }
  12843. +
  12844. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  12845. +
  12846. + DBG("PCI: read config: data=%08x raw=%08x\n",
  12847. + (data >> (8 * (where & 3))) & mask[size & 7], data);
  12848. +
  12849. + *value = (data >> (8 * (where & 3))) & mask[size & 7];
  12850. +
  12851. + /*
  12852. + * PCI controller bug: sometimes reads to the PCI_COMMAND register
  12853. + * return 0xffff, even though the PCI trace shows the correct value.
  12854. + * Work around this by retrying reads to this register
  12855. + */
  12856. + if (where == PCI_COMMAND && (*value & 0xffff) == 0xffff && retry++ < 2)
  12857. + goto retry;
  12858. +
  12859. + return ret;
  12860. +}
  12861. +
  12862. +static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  12863. + int where, int size, u32 value)
  12864. +{
  12865. + void __iomem *base = ar71xx_pcicfg_base;
  12866. + unsigned long flags;
  12867. + int ret;
  12868. +
  12869. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n",
  12870. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  12871. + where, size, value);
  12872. +
  12873. + value = value << (8 * (where & 3));
  12874. + ret = PCIBIOS_SUCCESSFUL;
  12875. +
  12876. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  12877. + if (bus->number == 0 && devfn == 0) {
  12878. + u32 t;
  12879. +
  12880. + t = PCI_CRP_CMD_WRITE | (where & ~3);
  12881. + t |= ar71xx_pci_get_ble(where, size, 1);
  12882. +
  12883. + DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value);
  12884. +
  12885. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  12886. + __raw_writel(value, base + PCI_REG_CRP_WRDATA);
  12887. + } else {
  12888. + int err;
  12889. +
  12890. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  12891. + PCI_CFG_CMD_WRITE);
  12892. +
  12893. + if (err == 0)
  12894. + __raw_writel(value, base + PCI_REG_CFG_WRDATA);
  12895. + else
  12896. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  12897. + }
  12898. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  12899. +
  12900. + return ret;
  12901. +}
  12902. +
  12903. +static void ar71xx_pci_fixup(struct pci_dev *dev)
  12904. +{
  12905. + u32 t;
  12906. +
  12907. + if (!ar71xx_pci_fixup_enable)
  12908. + return;
  12909. +
  12910. + if (dev->bus->number != 0 || dev->devfn != 0)
  12911. + return;
  12912. +
  12913. + DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev),
  12914. + dev->vendor, dev->device);
  12915. +
  12916. + /* setup COMMAND register */
  12917. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
  12918. + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
  12919. +
  12920. + pci_write_config_word(dev, PCI_COMMAND, t);
  12921. +}
  12922. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup);
  12923. +
  12924. +int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  12925. + uint8_t pin)
  12926. +{
  12927. + int irq = -1;
  12928. + int i;
  12929. +
  12930. + slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE;
  12931. +
  12932. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  12933. + struct ar71xx_pci_irq *entry;
  12934. +
  12935. + entry = &ar71xx_pci_irq_map[i];
  12936. + if (entry->slot == slot && entry->pin == pin) {
  12937. + irq = entry->irq;
  12938. + break;
  12939. + }
  12940. + }
  12941. +
  12942. + if (irq < 0) {
  12943. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  12944. + pin, pci_name((struct pci_dev *)dev));
  12945. + } else {
  12946. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  12947. + irq, pin, pci_name((struct pci_dev *)dev));
  12948. + }
  12949. +
  12950. + return irq;
  12951. +}
  12952. +
  12953. +static struct pci_ops ar71xx_pci_ops = {
  12954. + .read = ar71xx_pci_read_config,
  12955. + .write = ar71xx_pci_write_config,
  12956. +};
  12957. +
  12958. +static struct resource ar71xx_pci_io_resource = {
  12959. + .name = "PCI IO space",
  12960. + .start = 0,
  12961. + .end = 0,
  12962. + .flags = IORESOURCE_IO,
  12963. +};
  12964. +
  12965. +static struct resource ar71xx_pci_mem_resource = {
  12966. + .name = "PCI memory space",
  12967. + .start = AR71XX_PCI_MEM_BASE,
  12968. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  12969. + .flags = IORESOURCE_MEM
  12970. +};
  12971. +
  12972. +static struct pci_controller ar71xx_pci_controller = {
  12973. + .pci_ops = &ar71xx_pci_ops,
  12974. + .mem_resource = &ar71xx_pci_mem_resource,
  12975. + .io_resource = &ar71xx_pci_io_resource,
  12976. +};
  12977. +
  12978. +static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  12979. +{
  12980. + void __iomem *base = ar71xx_reset_base;
  12981. + u32 pending;
  12982. +
  12983. + pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
  12984. + __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  12985. +
  12986. + if (pending & PCI_INT_DEV0)
  12987. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  12988. +
  12989. + else if (pending & PCI_INT_DEV1)
  12990. + generic_handle_irq(AR71XX_PCI_IRQ_DEV1);
  12991. +
  12992. + else if (pending & PCI_INT_DEV2)
  12993. + generic_handle_irq(AR71XX_PCI_IRQ_DEV2);
  12994. +
  12995. + else if (pending & PCI_INT_CORE)
  12996. + generic_handle_irq(AR71XX_PCI_IRQ_CORE);
  12997. +
  12998. + else
  12999. + spurious_interrupt();
  13000. +}
  13001. +
  13002. +static void ar71xx_pci_irq_unmask(struct irq_data *d)
  13003. +{
  13004. + unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE;
  13005. + void __iomem *base = ar71xx_reset_base;
  13006. + u32 t;
  13007. +
  13008. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13009. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13010. +
  13011. + /* flush write */
  13012. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13013. +}
  13014. +
  13015. +static void ar71xx_pci_irq_mask(struct irq_data *d)
  13016. +{
  13017. + unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE;
  13018. + void __iomem *base = ar71xx_reset_base;
  13019. + u32 t;
  13020. +
  13021. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13022. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13023. +
  13024. + /* flush write */
  13025. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13026. +}
  13027. +
  13028. +static struct irq_chip ar71xx_pci_irq_chip = {
  13029. + .name = "AR71XX PCI ",
  13030. + .irq_mask = ar71xx_pci_irq_mask,
  13031. + .irq_unmask = ar71xx_pci_irq_unmask,
  13032. + .irq_mask_ack = ar71xx_pci_irq_mask,
  13033. +};
  13034. +
  13035. +static void __init ar71xx_pci_irq_init(void)
  13036. +{
  13037. + void __iomem *base = ar71xx_reset_base;
  13038. + int i;
  13039. +
  13040. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  13041. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
  13042. +
  13043. + for (i = AR71XX_PCI_IRQ_BASE;
  13044. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++)
  13045. + irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
  13046. + handle_level_irq);
  13047. +
  13048. + irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
  13049. +}
  13050. +
  13051. +int __init ar71xx_pcibios_init(void)
  13052. +{
  13053. + void __iomem *ddr_base = ar71xx_ddr_base;
  13054. +
  13055. + ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  13056. + ar71xx_pci_delay();
  13057. +
  13058. + ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  13059. + ar71xx_pci_delay();
  13060. +
  13061. + ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE,
  13062. + AR71XX_PCI_CFG_SIZE);
  13063. + if (ar71xx_pcicfg_base == NULL)
  13064. + return -ENOMEM;
  13065. +
  13066. + __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
  13067. + __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
  13068. + __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
  13069. + __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
  13070. + __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
  13071. + __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
  13072. + __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
  13073. + __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
  13074. +
  13075. + ar71xx_pci_delay();
  13076. +
  13077. + /* clear bus errors */
  13078. + (void)ar71xx_pci_be_handler(1);
  13079. +
  13080. + ar71xx_pci_fixup_enable = 1;
  13081. + ar71xx_pci_irq_init();
  13082. + register_pci_controller(&ar71xx_pci_controller);
  13083. +
  13084. + return 0;
  13085. +}
  13086. diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c
  13087. --- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100
  13088. +++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-08-24 18:17:24.000000000 +0200
  13089. @@ -0,0 +1,389 @@
  13090. +/*
  13091. + * Atheros AR724x PCI host controller driver
  13092. + *
  13093. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  13094. + *
  13095. + * Parts of this file are based on Atheros' 2.6.15 BSP
  13096. + *
  13097. + * This program is free software; you can redistribute it and/or modify it
  13098. + * under the terms of the GNU General Public License version 2 as published
  13099. + * by the Free Software Foundation.
  13100. + */
  13101. +
  13102. +#include <linux/resource.h>
  13103. +#include <linux/types.h>
  13104. +#include <linux/delay.h>
  13105. +#include <linux/bitops.h>
  13106. +#include <linux/pci.h>
  13107. +#include <linux/pci_regs.h>
  13108. +#include <linux/interrupt.h>
  13109. +
  13110. +#include <asm/mach-ar71xx/ar71xx.h>
  13111. +#include <asm/mach-ar71xx/pci.h>
  13112. +
  13113. +#undef DEBUG
  13114. +#ifdef DEBUG
  13115. +#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args)
  13116. +#else
  13117. +#define DBG(fmt, args...)
  13118. +#endif
  13119. +
  13120. +static void __iomem *ar724x_pci_localcfg_base;
  13121. +static void __iomem *ar724x_pci_devcfg_base;
  13122. +static void __iomem *ar724x_pci_ctrl_base;
  13123. +static int ar724x_pci_fixup_enable;
  13124. +
  13125. +static DEFINE_SPINLOCK(ar724x_pci_lock);
  13126. +
  13127. +static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value)
  13128. +{
  13129. + unsigned long flags;
  13130. + u32 data;
  13131. +
  13132. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  13133. + data = __raw_readl(base + (where & ~3));
  13134. +
  13135. + switch (size) {
  13136. + case 1:
  13137. + if (where & 1)
  13138. + data >>= 8;
  13139. + if (where & 2)
  13140. + data >>= 16;
  13141. + data &= 0xFF;
  13142. + break;
  13143. + case 2:
  13144. + if (where & 2)
  13145. + data >>= 16;
  13146. + data &= 0xFFFF;
  13147. + break;
  13148. + }
  13149. +
  13150. + *value = data;
  13151. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  13152. +}
  13153. +
  13154. +static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value)
  13155. +{
  13156. + unsigned long flags;
  13157. + u32 data;
  13158. + int s;
  13159. +
  13160. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  13161. + data = __raw_readl(base + (where & ~3));
  13162. +
  13163. + switch (size) {
  13164. + case 1:
  13165. + s = ((where & 3) << 3);
  13166. + data &= ~(0xFF << s);
  13167. + data |= ((value & 0xFF) << s);
  13168. + break;
  13169. + case 2:
  13170. + s = ((where & 2) << 3);
  13171. + data &= ~(0xFFFF << s);
  13172. + data |= ((value & 0xFFFF) << s);
  13173. + break;
  13174. + case 4:
  13175. + data = value;
  13176. + break;
  13177. + }
  13178. +
  13179. + __raw_writel(data, base + (where & ~3));
  13180. + /* flush write */
  13181. + (void)__raw_readl(base + (where & ~3));
  13182. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  13183. +}
  13184. +
  13185. +static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  13186. + int where, int size, u32 *value)
  13187. +{
  13188. +
  13189. + if (bus->number != 0 || devfn != 0)
  13190. + return PCIBIOS_DEVICE_NOT_FOUND;
  13191. +
  13192. + ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value);
  13193. +
  13194. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  13195. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  13196. + where, size, *value);
  13197. +
  13198. + /*
  13199. + * WAR for BAR issue - We are unable to access the PCI device space
  13200. + * if we set the BAR with proper base address
  13201. + */
  13202. + if ((where == 0x10) && (size == 4)) {
  13203. + u32 val;
  13204. + val = (ar71xx_soc == AR71XX_SOC_AR7240) ? 0xffff : 0x1000ffff;
  13205. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, val);
  13206. + }
  13207. +
  13208. + return PCIBIOS_SUCCESSFUL;
  13209. +}
  13210. +
  13211. +static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  13212. + int where, int size, u32 value)
  13213. +{
  13214. + if (bus->number != 0 || devfn != 0)
  13215. + return PCIBIOS_DEVICE_NOT_FOUND;
  13216. +
  13217. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  13218. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  13219. + where, size, value);
  13220. +
  13221. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value);
  13222. +
  13223. + return PCIBIOS_SUCCESSFUL;
  13224. +}
  13225. +
  13226. +static void ar724x_pci_fixup(struct pci_dev *dev)
  13227. +{
  13228. + u16 cmd;
  13229. +
  13230. + if (!ar724x_pci_fixup_enable)
  13231. + return;
  13232. +
  13233. + if (dev->bus->number != 0 || dev->devfn != 0)
  13234. + return;
  13235. +
  13236. + /* setup COMMAND register */
  13237. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  13238. + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
  13239. + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
  13240. + PCI_COMMAND_FAST_BACK;
  13241. +
  13242. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  13243. +}
  13244. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup);
  13245. +
  13246. +int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  13247. + uint8_t pin)
  13248. +{
  13249. + int irq = -1;
  13250. + int i;
  13251. +
  13252. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  13253. + struct ar71xx_pci_irq *entry;
  13254. + entry = &ar71xx_pci_irq_map[i];
  13255. +
  13256. + if (entry->slot == slot && entry->pin == pin) {
  13257. + irq = entry->irq;
  13258. + break;
  13259. + }
  13260. + }
  13261. +
  13262. + if (irq < 0)
  13263. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  13264. + pin, pci_name((struct pci_dev *)dev));
  13265. + else
  13266. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  13267. + irq, pin, pci_name((struct pci_dev *)dev));
  13268. +
  13269. + return irq;
  13270. +}
  13271. +
  13272. +static struct pci_ops ar724x_pci_ops = {
  13273. + .read = ar724x_pci_read_config,
  13274. + .write = ar724x_pci_write_config,
  13275. +};
  13276. +
  13277. +static struct resource ar724x_pci_io_resource = {
  13278. + .name = "PCI IO space",
  13279. + .start = 0,
  13280. + .end = 0,
  13281. + .flags = IORESOURCE_IO,
  13282. +};
  13283. +
  13284. +static struct resource ar724x_pci_mem_resource = {
  13285. + .name = "PCI memory space",
  13286. + .start = AR71XX_PCI_MEM_BASE,
  13287. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  13288. + .flags = IORESOURCE_MEM
  13289. +};
  13290. +
  13291. +static struct pci_controller ar724x_pci_controller = {
  13292. + .pci_ops = &ar724x_pci_ops,
  13293. + .mem_resource = &ar724x_pci_mem_resource,
  13294. + .io_resource = &ar724x_pci_io_resource,
  13295. +};
  13296. +
  13297. +static void __init ar724x_pci_reset(void)
  13298. +{
  13299. + ar71xx_device_stop(AR724X_RESET_PCIE);
  13300. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY);
  13301. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL);
  13302. + udelay(100);
  13303. +
  13304. + ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL);
  13305. + udelay(100);
  13306. + ar71xx_device_start(AR724X_RESET_PCIE_PHY);
  13307. + ar71xx_device_start(AR724X_RESET_PCIE);
  13308. +}
  13309. +
  13310. +static int __init ar724x_pci_setup(void)
  13311. +{
  13312. + void __iomem *base = ar724x_pci_ctrl_base;
  13313. + u32 t;
  13314. +
  13315. + /* setup COMMAND register */
  13316. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE |
  13317. + PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK;
  13318. +
  13319. + ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t);
  13320. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000);
  13321. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000);
  13322. +
  13323. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  13324. + if (t != 0x7) {
  13325. + udelay(100000);
  13326. + __raw_writel(0, base + AR724X_PCI_REG_RESET);
  13327. + udelay(100);
  13328. + __raw_writel(4, base + AR724X_PCI_REG_RESET);
  13329. + udelay(100000);
  13330. + }
  13331. +
  13332. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  13333. + t = AR724X_PCI_APP_LTSSM_ENABLE;
  13334. + else
  13335. + t = 0x1ffc1;
  13336. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  13337. + /* flush write */
  13338. + (void) __raw_readl(base + AR724X_PCI_REG_APP);
  13339. + udelay(1000);
  13340. +
  13341. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  13342. + if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) {
  13343. + printk(KERN_WARNING "PCI: no PCIe module found\n");
  13344. + return -ENODEV;
  13345. + }
  13346. +
  13347. + if (ar71xx_soc == AR71XX_SOC_AR7241 ||
  13348. + ar71xx_soc == AR71XX_SOC_AR7242) {
  13349. + t = __raw_readl(base + AR724X_PCI_REG_APP);
  13350. + t |= BIT(16);
  13351. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  13352. + }
  13353. +
  13354. + return 0;
  13355. +}
  13356. +
  13357. +static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  13358. +{
  13359. + void __iomem *base = ar724x_pci_ctrl_base;
  13360. + u32 pending;
  13361. +
  13362. + pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
  13363. + __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  13364. +
  13365. + if (pending & AR724X_PCI_INT_DEV0)
  13366. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  13367. +
  13368. + else
  13369. + spurious_interrupt();
  13370. +}
  13371. +
  13372. +static void ar724x_pci_irq_unmask(struct irq_data *d)
  13373. +{
  13374. + void __iomem *base = ar724x_pci_ctrl_base;
  13375. + u32 t;
  13376. +
  13377. + switch (d->irq) {
  13378. + case AR71XX_PCI_IRQ_DEV0:
  13379. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  13380. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  13381. + base + AR724X_PCI_REG_INT_MASK);
  13382. + /* flush write */
  13383. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  13384. + }
  13385. +}
  13386. +
  13387. +static void ar724x_pci_irq_mask(struct irq_data *d)
  13388. +{
  13389. + void __iomem *base = ar724x_pci_ctrl_base;
  13390. + u32 t;
  13391. +
  13392. + switch (d->irq) {
  13393. + case AR71XX_PCI_IRQ_DEV0:
  13394. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  13395. + __raw_writel(t & ~AR724X_PCI_INT_DEV0,
  13396. + base + AR724X_PCI_REG_INT_MASK);
  13397. +
  13398. + /* flush write */
  13399. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  13400. +
  13401. + t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  13402. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  13403. + base + AR724X_PCI_REG_INT_STATUS);
  13404. +
  13405. + /* flush write */
  13406. + (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  13407. + }
  13408. +}
  13409. +
  13410. +static struct irq_chip ar724x_pci_irq_chip = {
  13411. + .name = "AR724X PCI ",
  13412. + .irq_mask = ar724x_pci_irq_mask,
  13413. + .irq_unmask = ar724x_pci_irq_unmask,
  13414. + .irq_mask_ack = ar724x_pci_irq_mask,
  13415. +};
  13416. +
  13417. +static void __init ar724x_pci_irq_init(void)
  13418. +{
  13419. + void __iomem *base = ar724x_pci_ctrl_base;
  13420. + u32 t;
  13421. + int i;
  13422. +
  13423. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  13424. + if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY |
  13425. + AR724X_RESET_PCIE_PHY_SERIAL)) {
  13426. + return;
  13427. + }
  13428. +
  13429. + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
  13430. + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
  13431. +
  13432. + for (i = AR71XX_PCI_IRQ_BASE;
  13433. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++)
  13434. + irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
  13435. + handle_level_irq);
  13436. +
  13437. + irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler);
  13438. +}
  13439. +
  13440. +int __init ar724x_pcibios_init(void)
  13441. +{
  13442. + int ret = -ENOMEM;
  13443. +
  13444. + ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE,
  13445. + AR724X_PCI_CRP_SIZE);
  13446. + if (ar724x_pci_localcfg_base == NULL)
  13447. + goto err;
  13448. +
  13449. + ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE,
  13450. + AR724X_PCI_CFG_SIZE);
  13451. + if (ar724x_pci_devcfg_base == NULL)
  13452. + goto err_unmap_localcfg;
  13453. +
  13454. + ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE,
  13455. + AR724X_PCI_CTRL_SIZE);
  13456. + if (ar724x_pci_ctrl_base == NULL)
  13457. + goto err_unmap_devcfg;
  13458. +
  13459. + ar724x_pci_reset();
  13460. + ret = ar724x_pci_setup();
  13461. + if (ret)
  13462. + goto err_unmap_ctrl;
  13463. +
  13464. + ar724x_pci_fixup_enable = 1;
  13465. + ar724x_pci_irq_init();
  13466. + register_pci_controller(&ar724x_pci_controller);
  13467. +
  13468. + return 0;
  13469. +
  13470. +err_unmap_ctrl:
  13471. + iounmap(ar724x_pci_ctrl_base);
  13472. +err_unmap_devcfg:
  13473. + iounmap(ar724x_pci_devcfg_base);
  13474. +err_unmap_localcfg:
  13475. + iounmap(ar724x_pci_localcfg_base);
  13476. +err:
  13477. + return ret;
  13478. +}
  13479. diff -Nur linux-2.6.39.orig/drivers/Makefile linux-2.6.39/drivers/Makefile
  13480. --- linux-2.6.39.orig/drivers/Makefile 2011-05-19 06:06:34.000000000 +0200
  13481. +++ linux-2.6.39/drivers/Makefile 2011-08-24 18:17:24.000000000 +0200
  13482. @@ -46,8 +46,8 @@
  13483. obj-$(CONFIG_SCSI) += scsi/
  13484. obj-$(CONFIG_ATA) += ata/
  13485. obj-$(CONFIG_TARGET_CORE) += target/
  13486. -obj-$(CONFIG_MTD) += mtd/
  13487. obj-$(CONFIG_SPI) += spi/
  13488. +obj-$(CONFIG_MTD) += mtd/
  13489. obj-y += net/
  13490. obj-$(CONFIG_ATM) += atm/
  13491. obj-$(CONFIG_FUSION) += message/
  13492. diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c
  13493. --- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100
  13494. +++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-08-24 18:17:24.000000000 +0200
  13495. @@ -0,0 +1,247 @@
  13496. +/*
  13497. + * NXP 74HC153 - Dual 4-input multiplexer GPIO driver
  13498. + *
  13499. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  13500. + *
  13501. + * This program is free software; you can redistribute it and/or modify
  13502. + * it under the terms of the GNU General Public License version 2 as
  13503. + * published by the Free Software Foundation.
  13504. + */
  13505. +
  13506. +#include <linux/module.h>
  13507. +#include <linux/init.h>
  13508. +#include <linux/gpio.h>
  13509. +#include <linux/slab.h>
  13510. +#include <linux/platform_device.h>
  13511. +#include <linux/nxp_74hc153.h>
  13512. +
  13513. +#define NXP_74HC153_NUM_GPIOS 8
  13514. +#define NXP_74HC153_S0_MASK 0x1
  13515. +#define NXP_74HC153_S1_MASK 0x2
  13516. +#define NXP_74HC153_BANK_MASK 0x4
  13517. +
  13518. +struct nxp_74hc153_chip {
  13519. + struct device *parent;
  13520. + struct gpio_chip gpio_chip;
  13521. + struct mutex lock;
  13522. +};
  13523. +
  13524. +static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc)
  13525. +{
  13526. + return container_of(gc, struct nxp_74hc153_chip, gpio_chip);
  13527. +}
  13528. +
  13529. +static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset)
  13530. +{
  13531. + return 0;
  13532. +}
  13533. +
  13534. +static int nxp_74hc153_direction_output(struct gpio_chip *gc,
  13535. + unsigned offset, int val)
  13536. +{
  13537. + return -EINVAL;
  13538. +}
  13539. +
  13540. +static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset)
  13541. +{
  13542. + struct nxp_74hc153_chip *nxp;
  13543. + struct nxp_74hc153_platform_data *pdata;
  13544. + unsigned s0;
  13545. + unsigned s1;
  13546. + unsigned pin;
  13547. + int ret;
  13548. +
  13549. + nxp = gpio_to_nxp(gc);
  13550. + pdata = nxp->parent->platform_data;
  13551. +
  13552. + s0 = !!(offset & NXP_74HC153_S0_MASK);
  13553. + s1 = !!(offset & NXP_74HC153_S1_MASK);
  13554. + pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y
  13555. + : pdata->gpio_pin_1y;
  13556. +
  13557. + mutex_lock(&nxp->lock);
  13558. + gpio_set_value(pdata->gpio_pin_s0, s0);
  13559. + gpio_set_value(pdata->gpio_pin_s1, s1);
  13560. + ret = gpio_get_value(pin);
  13561. + mutex_unlock(&nxp->lock);
  13562. +
  13563. + return ret;
  13564. +}
  13565. +
  13566. +static void nxp_74hc153_set_value(struct gpio_chip *gc,
  13567. + unsigned offset, int val)
  13568. +{
  13569. + /* not supported */
  13570. +}
  13571. +
  13572. +static int __devinit nxp_74hc153_probe(struct platform_device *pdev)
  13573. +{
  13574. + struct nxp_74hc153_platform_data *pdata;
  13575. + struct nxp_74hc153_chip *nxp;
  13576. + struct gpio_chip *gc;
  13577. + int err;
  13578. +
  13579. + pdata = pdev->dev.platform_data;
  13580. + if (pdata == NULL) {
  13581. + dev_dbg(&pdev->dev, "no platform data specified\n");
  13582. + return -EINVAL;
  13583. + }
  13584. +
  13585. + nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL);
  13586. + if (nxp == NULL) {
  13587. + dev_err(&pdev->dev, "no memory for private data\n");
  13588. + return -ENOMEM;
  13589. + }
  13590. +
  13591. + err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev));
  13592. + if (err) {
  13593. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  13594. + pdata->gpio_pin_s0, err);
  13595. + goto err_free_nxp;
  13596. + }
  13597. +
  13598. + err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev));
  13599. + if (err) {
  13600. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  13601. + pdata->gpio_pin_s1, err);
  13602. + goto err_free_s0;
  13603. + }
  13604. +
  13605. + err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev));
  13606. + if (err) {
  13607. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  13608. + pdata->gpio_pin_1y, err);
  13609. + goto err_free_s1;
  13610. + }
  13611. +
  13612. + err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev));
  13613. + if (err) {
  13614. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  13615. + pdata->gpio_pin_2y, err);
  13616. + goto err_free_1y;
  13617. + }
  13618. +
  13619. + err = gpio_direction_output(pdata->gpio_pin_s0, 0);
  13620. + if (err) {
  13621. + dev_err(&pdev->dev,
  13622. + "unable to set direction of gpio %u, err=%d\n",
  13623. + pdata->gpio_pin_s0, err);
  13624. + goto err_free_2y;
  13625. + }
  13626. +
  13627. + err = gpio_direction_output(pdata->gpio_pin_s1, 0);
  13628. + if (err) {
  13629. + dev_err(&pdev->dev,
  13630. + "unable to set direction of gpio %u, err=%d\n",
  13631. + pdata->gpio_pin_s1, err);
  13632. + goto err_free_2y;
  13633. + }
  13634. +
  13635. + err = gpio_direction_input(pdata->gpio_pin_1y);
  13636. + if (err) {
  13637. + dev_err(&pdev->dev,
  13638. + "unable to set direction of gpio %u, err=%d\n",
  13639. + pdata->gpio_pin_1y, err);
  13640. + goto err_free_2y;
  13641. + }
  13642. +
  13643. + err = gpio_direction_input(pdata->gpio_pin_2y);
  13644. + if (err) {
  13645. + dev_err(&pdev->dev,
  13646. + "unable to set direction of gpio %u, err=%d\n",
  13647. + pdata->gpio_pin_2y, err);
  13648. + goto err_free_2y;
  13649. + }
  13650. +
  13651. + nxp->parent = &pdev->dev;
  13652. + mutex_init(&nxp->lock);
  13653. +
  13654. + gc = &nxp->gpio_chip;
  13655. +
  13656. + gc->direction_input = nxp_74hc153_direction_input;
  13657. + gc->direction_output = nxp_74hc153_direction_output;
  13658. + gc->get = nxp_74hc153_get_value;
  13659. + gc->set = nxp_74hc153_set_value;
  13660. + gc->can_sleep = 1;
  13661. +
  13662. + gc->base = pdata->gpio_base;
  13663. + gc->ngpio = NXP_74HC153_NUM_GPIOS;
  13664. + gc->label = dev_name(nxp->parent);
  13665. + gc->dev = nxp->parent;
  13666. + gc->owner = THIS_MODULE;
  13667. +
  13668. + err = gpiochip_add(&nxp->gpio_chip);
  13669. + if (err) {
  13670. + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
  13671. + goto err_free_2y;
  13672. + }
  13673. +
  13674. + platform_set_drvdata(pdev, nxp);
  13675. + return 0;
  13676. +
  13677. +err_free_2y:
  13678. + gpio_free(pdata->gpio_pin_2y);
  13679. +err_free_1y:
  13680. + gpio_free(pdata->gpio_pin_1y);
  13681. +err_free_s1:
  13682. + gpio_free(pdata->gpio_pin_s1);
  13683. +err_free_s0:
  13684. + gpio_free(pdata->gpio_pin_s0);
  13685. +err_free_nxp:
  13686. + kfree(nxp);
  13687. + return err;
  13688. +}
  13689. +
  13690. +static int nxp_74hc153_remove(struct platform_device *pdev)
  13691. +{
  13692. + struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev);
  13693. + struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data;
  13694. +
  13695. + if (nxp) {
  13696. + int err;
  13697. +
  13698. + err = gpiochip_remove(&nxp->gpio_chip);
  13699. + if (err) {
  13700. + dev_err(&pdev->dev,
  13701. + "unable to remove gpio chip, err=%d\n",
  13702. + err);
  13703. + return err;
  13704. + }
  13705. +
  13706. + gpio_free(pdata->gpio_pin_2y);
  13707. + gpio_free(pdata->gpio_pin_1y);
  13708. + gpio_free(pdata->gpio_pin_s1);
  13709. + gpio_free(pdata->gpio_pin_s0);
  13710. +
  13711. + kfree(nxp);
  13712. + platform_set_drvdata(pdev, NULL);
  13713. + }
  13714. +
  13715. + return 0;
  13716. +}
  13717. +
  13718. +static struct platform_driver nxp_74hc153_driver = {
  13719. + .probe = nxp_74hc153_probe,
  13720. + .remove = __devexit_p(nxp_74hc153_remove),
  13721. + .driver = {
  13722. + .name = NXP_74HC153_DRIVER_NAME,
  13723. + .owner = THIS_MODULE,
  13724. + },
  13725. +};
  13726. +
  13727. +static int __init nxp_74hc153_init(void)
  13728. +{
  13729. + return platform_driver_register(&nxp_74hc153_driver);
  13730. +}
  13731. +subsys_initcall(nxp_74hc153_init);
  13732. +
  13733. +static void __exit nxp_74hc153_exit(void)
  13734. +{
  13735. + platform_driver_unregister(&nxp_74hc153_driver);
  13736. +}
  13737. +module_exit(nxp_74hc153_exit);
  13738. +
  13739. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  13740. +MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153");
  13741. +MODULE_LICENSE("GPL v2");
  13742. +MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME);
  13743. diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c
  13744. --- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100
  13745. +++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-08-24 18:17:24.000000000 +0200
  13746. @@ -0,0 +1,141 @@
  13747. +/*
  13748. + * LED driver for the RouterBOARD 750
  13749. + *
  13750. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  13751. + *
  13752. + * This program is free software; you can redistribute it and/or modify
  13753. + * it under the terms of the GNU General Public License version 2 as
  13754. + * published by the Free Software Foundation.
  13755. + *
  13756. + */
  13757. +#include <linux/kernel.h>
  13758. +#include <linux/init.h>
  13759. +#include <linux/platform_device.h>
  13760. +#include <linux/leds.h>
  13761. +#include <linux/slab.h>
  13762. +
  13763. +#include <asm/mach-ar71xx/mach-rb750.h>
  13764. +
  13765. +#define DRV_NAME "leds-rb750"
  13766. +
  13767. +struct rb750_led_dev {
  13768. + struct led_classdev cdev;
  13769. + u32 mask;
  13770. + int active_low;
  13771. +};
  13772. +
  13773. +struct rb750_led_drvdata {
  13774. + struct rb750_led_dev *led_devs;
  13775. + int num_leds;
  13776. +};
  13777. +
  13778. +static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev)
  13779. +{
  13780. + return (struct rb750_led_dev *)container_of(led_cdev,
  13781. + struct rb750_led_dev, cdev);
  13782. +}
  13783. +
  13784. +static void rb750_led_brightness_set(struct led_classdev *led_cdev,
  13785. + enum led_brightness value)
  13786. +{
  13787. + struct rb750_led_dev *rbled = to_rbled(led_cdev);
  13788. + int level;
  13789. +
  13790. + level = (value == LED_OFF) ? 0 : 1;
  13791. + level ^= rbled->active_low;
  13792. +
  13793. + if (level)
  13794. + rb750_latch_change(0, rbled->mask);
  13795. + else
  13796. + rb750_latch_change(rbled->mask, 0);
  13797. +}
  13798. +
  13799. +static int __devinit rb750_led_probe(struct platform_device *pdev)
  13800. +{
  13801. + struct rb750_led_platform_data *pdata;
  13802. + struct rb750_led_drvdata *drvdata;
  13803. + int ret = 0;
  13804. + int i;
  13805. +
  13806. + pdata = pdev->dev.platform_data;
  13807. + if (!pdata)
  13808. + return -EINVAL;
  13809. +
  13810. + drvdata = kzalloc(sizeof(struct rb750_led_drvdata) +
  13811. + sizeof(struct rb750_led_dev) * pdata->num_leds,
  13812. + GFP_KERNEL);
  13813. + if (!drvdata)
  13814. + return -ENOMEM;
  13815. +
  13816. + drvdata->num_leds = pdata->num_leds;
  13817. + drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1];
  13818. +
  13819. + for (i = 0; i < drvdata->num_leds; i++) {
  13820. + struct rb750_led_dev *rbled = &drvdata->led_devs[i];
  13821. + struct rb750_led_data *led_data = &pdata->leds[i];
  13822. +
  13823. + rbled->cdev.name = led_data->name;
  13824. + rbled->cdev.default_trigger = led_data->default_trigger;
  13825. + rbled->cdev.brightness_set = rb750_led_brightness_set;
  13826. + rbled->cdev.brightness = LED_OFF;
  13827. +
  13828. + rbled->mask = led_data->mask;
  13829. + rbled->active_low = !!led_data->active_low;
  13830. +
  13831. + ret = led_classdev_register(&pdev->dev, &rbled->cdev);
  13832. + if (ret)
  13833. + goto err;
  13834. + }
  13835. +
  13836. + platform_set_drvdata(pdev, drvdata);
  13837. + return 0;
  13838. +
  13839. +err:
  13840. + for (i = i - 1; i >= 0; i--)
  13841. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  13842. +
  13843. + kfree(drvdata);
  13844. + return ret;
  13845. +}
  13846. +
  13847. +static int __devexit rb750_led_remove(struct platform_device *pdev)
  13848. +{
  13849. + struct rb750_led_drvdata *drvdata;
  13850. + int i;
  13851. +
  13852. + drvdata = platform_get_drvdata(pdev);
  13853. + for (i = 0; i < drvdata->num_leds; i++)
  13854. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  13855. +
  13856. + kfree(drvdata);
  13857. + return 0;
  13858. +}
  13859. +
  13860. +static struct platform_driver rb750_led_driver = {
  13861. + .probe = rb750_led_probe,
  13862. + .remove = __devexit_p(rb750_led_remove),
  13863. + .driver = {
  13864. + .name = DRV_NAME,
  13865. + .owner = THIS_MODULE,
  13866. + },
  13867. +};
  13868. +
  13869. +MODULE_ALIAS("platform:leds-rb750");
  13870. +
  13871. +static int __init rb750_led_init(void)
  13872. +{
  13873. + return platform_driver_register(&rb750_led_driver);
  13874. +}
  13875. +
  13876. +static void __exit rb750_led_exit(void)
  13877. +{
  13878. + platform_driver_unregister(&rb750_led_driver);
  13879. +}
  13880. +
  13881. +module_init(rb750_led_init);
  13882. +module_exit(rb750_led_exit);
  13883. +
  13884. +MODULE_DESCRIPTION(DRV_NAME);
  13885. +MODULE_DESCRIPTION("LED driver for the RouterBOARD 750");
  13886. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  13887. +MODULE_LICENSE("GPL v2");
  13888. diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c
  13889. --- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100
  13890. +++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-08-24 18:17:24.000000000 +0200
  13891. @@ -0,0 +1,75 @@
  13892. +/*
  13893. + * USB LED driver for the NETGEAR WNDR3700
  13894. + *
  13895. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  13896. + *
  13897. + * This program is free software; you can redistribute it and/or modify it
  13898. + * under the terms of the GNU General Public License version 2 as published
  13899. + * by the Free Software Foundation.
  13900. + */
  13901. +
  13902. +#include <linux/leds.h>
  13903. +#include <linux/module.h>
  13904. +#include <linux/platform_device.h>
  13905. +
  13906. +#include <asm/mach-ar71xx/ar71xx.h>
  13907. +
  13908. +#define DRIVER_NAME "wndr3700-led-usb"
  13909. +
  13910. +static void wndr3700_usb_led_set(struct led_classdev *cdev,
  13911. + enum led_brightness brightness)
  13912. +{
  13913. + if (brightness)
  13914. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  13915. + else
  13916. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  13917. +}
  13918. +
  13919. +static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev)
  13920. +{
  13921. + return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL;
  13922. +}
  13923. +
  13924. +static struct led_classdev wndr3700_usb_led = {
  13925. + .name = "wndr3700:green:usb",
  13926. + .brightness_set = wndr3700_usb_led_set,
  13927. + .brightness_get = wndr3700_usb_led_get,
  13928. +};
  13929. +
  13930. +static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev)
  13931. +{
  13932. + return led_classdev_register(&pdev->dev, &wndr3700_usb_led);
  13933. +}
  13934. +
  13935. +static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev)
  13936. +{
  13937. + led_classdev_unregister(&wndr3700_usb_led);
  13938. + return 0;
  13939. +}
  13940. +
  13941. +static struct platform_driver wndr3700_usb_led_driver = {
  13942. + .probe = wndr3700_usb_led_probe,
  13943. + .remove = __devexit_p(wndr3700_usb_led_remove),
  13944. + .driver = {
  13945. + .name = DRIVER_NAME,
  13946. + .owner = THIS_MODULE,
  13947. + },
  13948. +};
  13949. +
  13950. +static int __init wndr3700_usb_led_init(void)
  13951. +{
  13952. + return platform_driver_register(&wndr3700_usb_led_driver);
  13953. +}
  13954. +
  13955. +static void __exit wndr3700_usb_led_exit(void)
  13956. +{
  13957. + platform_driver_unregister(&wndr3700_usb_led_driver);
  13958. +}
  13959. +
  13960. +module_init(wndr3700_usb_led_init);
  13961. +module_exit(wndr3700_usb_led_exit);
  13962. +
  13963. +MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700");
  13964. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  13965. +MODULE_LICENSE("GPL v2");
  13966. +MODULE_ALIAS("platform:" DRIVER_NAME);
  13967. diff -Nur linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c
  13968. --- linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c 2011-05-19 06:06:34.000000000 +0200
  13969. +++ linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c 2011-08-24 18:17:24.000000000 +0200
  13970. @@ -39,7 +39,7 @@
  13971. #include <linux/mtd/xip.h>
  13972. #define AMD_BOOTLOC_BUG
  13973. -#define FORCE_WORD_WRITE 0
  13974. +#define FORCE_WORD_WRITE 1
  13975. #define MAX_WORD_RETRIES 3
  13976. @@ -50,7 +50,9 @@
  13977. static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
  13978. static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
  13979. +#if !FORCE_WORD_WRITE
  13980. static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
  13981. +#endif
  13982. static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
  13983. static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
  13984. static void cfi_amdstd_sync (struct mtd_info *);
  13985. @@ -186,6 +188,7 @@
  13986. }
  13987. #endif
  13988. +#if !FORCE_WORD_WRITE
  13989. static void fixup_use_write_buffers(struct mtd_info *mtd)
  13990. {
  13991. struct map_info *map = mtd->priv;
  13992. @@ -195,6 +198,7 @@
  13993. mtd->write = cfi_amdstd_write_buffers;
  13994. }
  13995. }
  13996. +#endif /* !FORCE_WORD_WRITE */
  13997. /* Atmel chips don't use the same PRI format as AMD chips */
  13998. static void fixup_convert_atmel_pri(struct mtd_info *mtd)
  13999. @@ -1377,6 +1381,7 @@
  14000. /*
  14001. * FIXME: interleaved mode not tested, and probably not supported!
  14002. */
  14003. +#if !FORCE_WORD_WRITE
  14004. static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
  14005. unsigned long adr, const u_char *buf,
  14006. int len)
  14007. @@ -1487,7 +1492,6 @@
  14008. return ret;
  14009. }
  14010. -
  14011. static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
  14012. size_t *retlen, const u_char *buf)
  14013. {
  14014. @@ -1566,6 +1570,7 @@
  14015. return 0;
  14016. }
  14017. +#endif /* !FORCE_WORD_WRITE */
  14018. /*
  14019. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig
  14020. --- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200
  14021. +++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-08-24 18:17:24.000000000 +0200
  14022. @@ -260,6 +260,13 @@
  14023. Support for parsing CFE image tag and creating MTD partitions on
  14024. Broadcom BCM63xx boards.
  14025. +config MTD_AR91XX_FLASH
  14026. + tristate "Atheros AR91xx parallel flash support"
  14027. + depends on ATHEROS_AR71XX
  14028. + select MTD_COMPLEX_MAPPINGS
  14029. + help
  14030. + Parallel flash driver for the Atheros AR91xx based boards.
  14031. +
  14032. config MTD_DILNETPC
  14033. tristate "CFI Flash device mapped on DIL/Net PC"
  14034. depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
  14035. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile
  14036. --- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200
  14037. +++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-08-24 18:17:24.000000000 +0200
  14038. @@ -40,6 +40,7 @@
  14039. obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o
  14040. obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
  14041. obj-$(CONFIG_MTD_PCI) += pci.o
  14042. +obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o
  14043. obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
  14044. obj-$(CONFIG_MTD_EDB7312) += edb7312.o
  14045. obj-$(CONFIG_MTD_IMPA7) += impa7.o
  14046. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c
  14047. --- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100
  14048. +++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-08-24 18:17:24.000000000 +0200
  14049. @@ -0,0 +1,310 @@
  14050. +/*
  14051. + * Parallel flash driver for the Atheros AR91xx SoC
  14052. + *
  14053. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  14054. + *
  14055. + * This program is free software; you can redistribute it and/or modify
  14056. + * it under the terms of the GNU General Public License version 2 as
  14057. + * published by the Free Software Foundation.
  14058. + *
  14059. + */
  14060. +
  14061. +#include <linux/module.h>
  14062. +#include <linux/types.h>
  14063. +#include <linux/kernel.h>
  14064. +#include <linux/init.h>
  14065. +#include <linux/slab.h>
  14066. +#include <linux/device.h>
  14067. +#include <linux/platform_device.h>
  14068. +#include <linux/mtd/mtd.h>
  14069. +#include <linux/mtd/map.h>
  14070. +#include <linux/mtd/partitions.h>
  14071. +#include <linux/io.h>
  14072. +
  14073. +#include <asm/mach-ar71xx/ar71xx.h>
  14074. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  14075. +
  14076. +#define DRV_NAME "ar91xx-flash"
  14077. +
  14078. +struct ar91xx_flash_info {
  14079. + struct mtd_info *mtd;
  14080. + struct map_info map;
  14081. +#ifdef CONFIG_MTD_PARTITIONS
  14082. + int nr_parts;
  14083. + struct mtd_partition *parts;
  14084. +#endif
  14085. +};
  14086. +
  14087. +static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs)
  14088. +{
  14089. + map_word val;
  14090. +
  14091. + if (map_bankwidth_is_1(map))
  14092. + val.x[0] = __raw_readb(map->virt + (ofs ^ 3));
  14093. + else if (map_bankwidth_is_2(map))
  14094. + val.x[0] = __raw_readw(map->virt + (ofs ^ 2));
  14095. + else
  14096. + val = map_word_ff(map);
  14097. +
  14098. + return val;
  14099. +}
  14100. +
  14101. +static void ar91xx_flash_write(struct map_info *map, map_word d,
  14102. + unsigned long ofs)
  14103. +{
  14104. + if (map_bankwidth_is_1(map))
  14105. + __raw_writeb(d.x[0], map->virt + (ofs ^ 3));
  14106. + else if (map_bankwidth_is_2(map))
  14107. + __raw_writew(d.x[0], map->virt + (ofs ^ 2));
  14108. +
  14109. + mb();
  14110. +}
  14111. +
  14112. +static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs)
  14113. +{
  14114. + map_word ret;
  14115. +
  14116. + ar71xx_flash_acquire();
  14117. + ret = ar91xx_flash_read(map, ofs);
  14118. + ar71xx_flash_release();
  14119. +
  14120. + return ret;
  14121. +}
  14122. +
  14123. +static void ar91xx_flash_write_lock(struct map_info *map, map_word d,
  14124. + unsigned long ofs)
  14125. +{
  14126. + ar71xx_flash_acquire();
  14127. + ar91xx_flash_write(map, d, ofs);
  14128. + ar71xx_flash_release();
  14129. +}
  14130. +
  14131. +static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to,
  14132. + unsigned long from, ssize_t len)
  14133. +{
  14134. + ar71xx_flash_acquire();
  14135. + inline_map_copy_from(map, to, from, len);
  14136. + ar71xx_flash_release();
  14137. +}
  14138. +
  14139. +static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to,
  14140. + const void *from, ssize_t len)
  14141. +{
  14142. + ar71xx_flash_acquire();
  14143. + inline_map_copy_to(map, to, from, len);
  14144. + ar71xx_flash_release();
  14145. +}
  14146. +
  14147. +static int ar91xx_flash_remove(struct platform_device *pdev)
  14148. +{
  14149. + struct ar91xx_flash_platform_data *pdata;
  14150. + struct ar91xx_flash_info *info;
  14151. +
  14152. + info = platform_get_drvdata(pdev);
  14153. + if (info == NULL)
  14154. + return 0;
  14155. +
  14156. + platform_set_drvdata(pdev, NULL);
  14157. +
  14158. + if (info->mtd == NULL)
  14159. + return 0;
  14160. +
  14161. + pdata = pdev->dev.platform_data;
  14162. +#ifdef CONFIG_MTD_PARTITIONS
  14163. + if (info->nr_parts) {
  14164. + del_mtd_partitions(info->mtd);
  14165. + kfree(info->parts);
  14166. + } else if (pdata->nr_parts) {
  14167. + del_mtd_partitions(info->mtd);
  14168. + } else {
  14169. + del_mtd_device(info->mtd);
  14170. + }
  14171. +#else
  14172. + del_mtd_device(info->mtd);
  14173. +#endif
  14174. + map_destroy(info->mtd);
  14175. +
  14176. + return 0;
  14177. +}
  14178. +
  14179. +static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
  14180. +#ifdef CONFIG_MTD_PARTITIONS
  14181. +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  14182. +#endif
  14183. +
  14184. +static int ar91xx_flash_probe(struct platform_device *pdev)
  14185. +{
  14186. + struct ar91xx_flash_platform_data *pdata;
  14187. + struct ar91xx_flash_info *info;
  14188. + struct resource *res;
  14189. + struct resource *region;
  14190. + const char **probe_type;
  14191. + int err = 0;
  14192. +
  14193. + pdata = pdev->dev.platform_data;
  14194. + if (pdata == NULL)
  14195. + return -EINVAL;
  14196. +
  14197. + info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info),
  14198. + GFP_KERNEL);
  14199. + if (info == NULL) {
  14200. + err = -ENOMEM;
  14201. + goto err_out;
  14202. + }
  14203. +
  14204. + platform_set_drvdata(pdev, info);
  14205. +
  14206. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  14207. + if (res == NULL) {
  14208. + err = -ENOENT;
  14209. + goto err_out;
  14210. + }
  14211. +
  14212. + dev_info(&pdev->dev, "%.8llx at %.8llx\n",
  14213. + (unsigned long long)(res->end - res->start + 1),
  14214. + (unsigned long long)res->start);
  14215. +
  14216. + region = devm_request_mem_region(&pdev->dev,
  14217. + res->start, res->end - res->start + 1,
  14218. + dev_name(&pdev->dev));
  14219. + if (region == NULL) {
  14220. + dev_err(&pdev->dev, "could not reserve memory region\n");
  14221. + err = -ENOMEM;
  14222. + goto err_out;
  14223. + }
  14224. +
  14225. + info->map.name = dev_name(&pdev->dev);
  14226. + info->map.phys = res->start;
  14227. + info->map.size = res->end - res->start + 1;
  14228. + info->map.bankwidth = pdata->width;
  14229. +
  14230. + info->map.virt = devm_ioremap(&pdev->dev, info->map.phys,
  14231. + info->map.size);
  14232. + if (info->map.virt == NULL) {
  14233. + dev_err(&pdev->dev, "failed to ioremap flash region\n");
  14234. + err = -EIO;
  14235. + goto err_out;
  14236. + }
  14237. +
  14238. + simple_map_init(&info->map);
  14239. + if (pdata->is_shared) {
  14240. + info->map.read = ar91xx_flash_read_lock;
  14241. + info->map.write = ar91xx_flash_write_lock;
  14242. + info->map.copy_from = ar91xx_flash_copy_from_lock;
  14243. + info->map.copy_to = ar91xx_flash_copy_to_lock;
  14244. + } else {
  14245. + info->map.read = ar91xx_flash_read;
  14246. + info->map.write = ar91xx_flash_write;
  14247. + }
  14248. +
  14249. + probe_type = rom_probe_types;
  14250. + for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
  14251. + info->mtd = do_map_probe(*probe_type, &info->map);
  14252. +
  14253. + if (info->mtd == NULL) {
  14254. + dev_err(&pdev->dev, "map_probe failed\n");
  14255. + err = -ENXIO;
  14256. + goto err_out;
  14257. + }
  14258. +
  14259. + info->mtd->owner = THIS_MODULE;
  14260. +
  14261. +#ifdef CONFIG_MTD_PARTITIONS
  14262. + if (pdata->nr_parts) {
  14263. + dev_info(&pdev->dev, "using static partition mapping\n");
  14264. + add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
  14265. + return 0;
  14266. + }
  14267. +
  14268. + err = parse_mtd_partitions(info->mtd, part_probe_types,
  14269. + &info->parts, 0);
  14270. + if (err > 0) {
  14271. + add_mtd_partitions(info->mtd, info->parts, err);
  14272. + return 0;
  14273. + }
  14274. +#endif
  14275. +
  14276. + add_mtd_device(info->mtd);
  14277. + return 0;
  14278. +
  14279. +err_out:
  14280. + ar91xx_flash_remove(pdev);
  14281. + return err;
  14282. +}
  14283. +
  14284. +#ifdef CONFIG_PM
  14285. +static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state)
  14286. +{
  14287. + struct ar91xx_flash_info *info = platform_get_drvdata(dev);
  14288. + int ret = 0;
  14289. +
  14290. + if (info->mtd->suspend)
  14291. + ret = info->mtd->suspend(info->mtd);
  14292. +
  14293. + if (ret)
  14294. + goto fail;
  14295. +
  14296. + return 0;
  14297. +
  14298. +fail:
  14299. + if (info->mtd->suspend) {
  14300. + BUG_ON(!info->mtd->resume);
  14301. + info->mtd->resume(info->mtd);
  14302. + }
  14303. +
  14304. + return ret;
  14305. +}
  14306. +
  14307. +static int ar91xx_flash_resume(struct platform_device *pdev)
  14308. +{
  14309. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  14310. +
  14311. + if (info->mtd->resume)
  14312. + info->mtd->resume(info->mtd);
  14313. +
  14314. + return 0;
  14315. +}
  14316. +
  14317. +static void ar91xx_flash_shutdown(struct platform_device *pdev)
  14318. +{
  14319. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  14320. +
  14321. + if (info->mtd->suspend && info->mtd->resume)
  14322. + if (info->mtd->suspend(info->mtd) == 0)
  14323. + info->mtd->resume(info->mtd);
  14324. +}
  14325. +#else
  14326. +#define ar91xx_flash_suspend NULL
  14327. +#define ar91xx_flash_resume NULL
  14328. +#define ar91xx_flash_shutdown NULL
  14329. +#endif
  14330. +
  14331. +static struct platform_driver ar91xx_flash_driver = {
  14332. + .probe = ar91xx_flash_probe,
  14333. + .remove = ar91xx_flash_remove,
  14334. + .suspend = ar91xx_flash_suspend,
  14335. + .resume = ar91xx_flash_resume,
  14336. + .shutdown = ar91xx_flash_shutdown,
  14337. + .driver = {
  14338. + .name = DRV_NAME,
  14339. + .owner = THIS_MODULE,
  14340. + },
  14341. +};
  14342. +
  14343. +static int __init ar91xx_flash_init(void)
  14344. +{
  14345. + return platform_driver_register(&ar91xx_flash_driver);
  14346. +}
  14347. +
  14348. +static void __exit ar91xx_flash_exit(void)
  14349. +{
  14350. + platform_driver_unregister(&ar91xx_flash_driver);
  14351. +}
  14352. +
  14353. +module_init(ar91xx_flash_init);
  14354. +module_exit(ar91xx_flash_exit);
  14355. +
  14356. +MODULE_LICENSE("GPL v2");
  14357. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  14358. +MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC");
  14359. +MODULE_ALIAS("platform:" DRV_NAME);
  14360. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig
  14361. --- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200
  14362. +++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-08-24 18:17:24.000000000 +0200
  14363. @@ -531,4 +531,9 @@
  14364. Enables support for NAND Flash chips on the ST Microelectronics
  14365. Flexible Static Memory Controller (FSMC)
  14366. +config MTD_NAND_RB4XX
  14367. + tristate "NAND flash driver for RouterBoard 4xx series"
  14368. + depends on MTD_NAND && AR71XX_MACH_RB4XX
  14369. + select SPI_AR71XX
  14370. +
  14371. endif # MTD_NAND
  14372. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile
  14373. --- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200
  14374. +++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-08-24 18:17:24.000000000 +0200
  14375. @@ -34,6 +34,7 @@
  14376. obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
  14377. obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
  14378. obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
  14379. +obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
  14380. obj-$(CONFIG_MTD_ALAUDA) += alauda.o
  14381. obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
  14382. obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
  14383. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c
  14384. --- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100
  14385. +++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-08-24 18:17:24.000000000 +0200
  14386. @@ -0,0 +1,311 @@
  14387. +/*
  14388. + * NAND flash driver for the MikroTik RouterBoard 4xx series
  14389. + *
  14390. + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
  14391. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14392. + *
  14393. + * This file was based on the driver for Linux 2.6.22 published by
  14394. + * MikroTik for their RouterBoard 4xx series devices.
  14395. + *
  14396. + * This program is free software; you can redistribute it and/or modify it
  14397. + * under the terms of the GNU General Public License version 2 as published
  14398. + * by the Free Software Foundation.
  14399. + */
  14400. +
  14401. +#include <linux/init.h>
  14402. +#include <linux/mtd/nand.h>
  14403. +#include <linux/mtd/mtd.h>
  14404. +#include <linux/mtd/partitions.h>
  14405. +#include <linux/platform_device.h>
  14406. +#include <linux/delay.h>
  14407. +#include <linux/io.h>
  14408. +#include <linux/gpio.h>
  14409. +#include <linux/slab.h>
  14410. +
  14411. +#include <asm/mach-ar71xx/ar71xx.h>
  14412. +#include <asm/mach-ar71xx/rb4xx_cpld.h>
  14413. +
  14414. +#define DRV_NAME "rb4xx-nand"
  14415. +#define DRV_VERSION "0.2.0"
  14416. +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
  14417. +
  14418. +#define RB4XX_NAND_GPIO_READY 5
  14419. +#define RB4XX_NAND_GPIO_ALE 37
  14420. +#define RB4XX_NAND_GPIO_CLE 38
  14421. +#define RB4XX_NAND_GPIO_NCE 39
  14422. +
  14423. +struct rb4xx_nand_info {
  14424. + struct nand_chip chip;
  14425. + struct mtd_info mtd;
  14426. +};
  14427. +
  14428. +/*
  14429. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  14430. + * will not be able to find the kernel that we load.
  14431. + */
  14432. +static struct nand_ecclayout rb4xx_nand_ecclayout = {
  14433. + .eccbytes = 6,
  14434. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  14435. + .oobavail = 9,
  14436. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  14437. +};
  14438. +
  14439. +static struct mtd_partition rb4xx_nand_partitions[] = {
  14440. + {
  14441. + .name = "booter",
  14442. + .offset = 0,
  14443. + .size = (256 * 1024),
  14444. + .mask_flags = MTD_WRITEABLE,
  14445. + },
  14446. + {
  14447. + .name = "kernel",
  14448. + .offset = (256 * 1024),
  14449. + .size = (6 * 1024 * 1024) - (256 * 1024),
  14450. + },
  14451. + {
  14452. + .name = "rootfs",
  14453. + .offset = MTDPART_OFS_NXTBLK,
  14454. + .size = MTDPART_SIZ_FULL,
  14455. + },
  14456. +};
  14457. +
  14458. +static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
  14459. +{
  14460. + return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY);
  14461. +}
  14462. +
  14463. +static void rb4xx_nand_write_cmd(unsigned char cmd)
  14464. +{
  14465. + unsigned char data = cmd;
  14466. + int err;
  14467. +
  14468. + err = rb4xx_cpld_write(&data, 1);
  14469. + if (err)
  14470. + pr_err("rb4xx_nand: write cmd failed, err=%d\n", err);
  14471. +}
  14472. +
  14473. +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  14474. + unsigned int ctrl)
  14475. +{
  14476. + if (ctrl & NAND_CTRL_CHANGE) {
  14477. + gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE,
  14478. + (ctrl & NAND_CLE) ? 1 : 0);
  14479. + gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE,
  14480. + (ctrl & NAND_ALE) ? 1 : 0);
  14481. + gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE,
  14482. + (ctrl & NAND_NCE) ? 0 : 1);
  14483. + }
  14484. +
  14485. + if (cmd != NAND_CMD_NONE)
  14486. + rb4xx_nand_write_cmd(cmd);
  14487. +}
  14488. +
  14489. +static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd)
  14490. +{
  14491. + unsigned char data = 0;
  14492. + int err;
  14493. +
  14494. + err = rb4xx_cpld_read(&data, NULL, 1);
  14495. + if (err) {
  14496. + pr_err("rb4xx_nand: read data failed, err=%d\n", err);
  14497. + data = 0xff;
  14498. + }
  14499. +
  14500. + return data;
  14501. +}
  14502. +
  14503. +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf,
  14504. + int len)
  14505. +{
  14506. + int err;
  14507. +
  14508. + err = rb4xx_cpld_write(buf, len);
  14509. + if (err)
  14510. + pr_err("rb4xx_nand: write buf failed, err=%d\n", err);
  14511. +}
  14512. +
  14513. +static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf,
  14514. + int len)
  14515. +{
  14516. + int err;
  14517. +
  14518. + err = rb4xx_cpld_read(buf, NULL, len);
  14519. + if (err)
  14520. + pr_err("rb4xx_nand: read buf failed, err=%d\n", err);
  14521. +}
  14522. +
  14523. +static int __init rb4xx_nand_probe(struct platform_device *pdev)
  14524. +{
  14525. + struct rb4xx_nand_info *info;
  14526. + int ret;
  14527. +
  14528. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  14529. +
  14530. + ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY");
  14531. + if (ret) {
  14532. + dev_err(&pdev->dev, "unable to request gpio %d\n",
  14533. + RB4XX_NAND_GPIO_READY);
  14534. + goto err;
  14535. + }
  14536. +
  14537. + ret = gpio_direction_input(RB4XX_NAND_GPIO_READY);
  14538. + if (ret) {
  14539. + dev_err(&pdev->dev, "unable to set input mode on gpio %d\n",
  14540. + RB4XX_NAND_GPIO_READY);
  14541. + goto err_free_gpio_ready;
  14542. + }
  14543. +
  14544. + ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE");
  14545. + if (ret) {
  14546. + dev_err(&pdev->dev, "unable to request gpio %d\n",
  14547. + RB4XX_NAND_GPIO_ALE);
  14548. + goto err_free_gpio_ready;
  14549. + }
  14550. +
  14551. + ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0);
  14552. + if (ret) {
  14553. + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
  14554. + RB4XX_NAND_GPIO_ALE);
  14555. + goto err_free_gpio_ale;
  14556. + }
  14557. +
  14558. + ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE");
  14559. + if (ret) {
  14560. + dev_err(&pdev->dev, "unable to request gpio %d\n",
  14561. + RB4XX_NAND_GPIO_CLE);
  14562. + goto err_free_gpio_ale;
  14563. + }
  14564. +
  14565. + ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0);
  14566. + if (ret) {
  14567. + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
  14568. + RB4XX_NAND_GPIO_CLE);
  14569. + goto err_free_gpio_cle;
  14570. + }
  14571. +
  14572. + ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE");
  14573. + if (ret) {
  14574. + dev_err(&pdev->dev, "unable to request gpio %d\n",
  14575. + RB4XX_NAND_GPIO_NCE);
  14576. + goto err_free_gpio_cle;
  14577. + }
  14578. +
  14579. + ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1);
  14580. + if (ret) {
  14581. + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
  14582. + RB4XX_NAND_GPIO_ALE);
  14583. + goto err_free_gpio_nce;
  14584. + }
  14585. +
  14586. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  14587. + if (!info) {
  14588. + dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n");
  14589. + ret = -ENOMEM;
  14590. + goto err_free_gpio_nce;
  14591. + }
  14592. +
  14593. + info->chip.priv = &info;
  14594. + info->mtd.priv = &info->chip;
  14595. + info->mtd.owner = THIS_MODULE;
  14596. +
  14597. + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
  14598. + info->chip.dev_ready = rb4xx_nand_dev_ready;
  14599. + info->chip.read_byte = rb4xx_nand_read_byte;
  14600. + info->chip.write_buf = rb4xx_nand_write_buf;
  14601. + info->chip.read_buf = rb4xx_nand_read_buf;
  14602. +#if 0
  14603. + info->chip.verify_buf = rb4xx_nand_verify_buf;
  14604. +#endif
  14605. +
  14606. + info->chip.chip_delay = 25;
  14607. + info->chip.ecc.mode = NAND_ECC_SOFT;
  14608. + info->chip.options |= NAND_NO_AUTOINCR;
  14609. +
  14610. + platform_set_drvdata(pdev, info);
  14611. +
  14612. + ret = nand_scan_ident(&info->mtd, 1, NULL);
  14613. + if (ret) {
  14614. + ret = -ENXIO;
  14615. + goto err_free_info;
  14616. + }
  14617. +
  14618. + if (info->mtd.writesize == 512)
  14619. + info->chip.ecc.layout = &rb4xx_nand_ecclayout;
  14620. +
  14621. + ret = nand_scan_tail(&info->mtd);
  14622. + if (ret) {
  14623. + return -ENXIO;
  14624. + goto err_set_drvdata;
  14625. + }
  14626. +
  14627. +#ifdef CONFIG_MTD_PARTITIONS
  14628. + ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions,
  14629. + ARRAY_SIZE(rb4xx_nand_partitions));
  14630. +#else
  14631. + ret = add_mtd_device(&info->mtd);
  14632. +#endif
  14633. + if (ret)
  14634. + goto err_release_nand;
  14635. +
  14636. + return 0;
  14637. +
  14638. +err_release_nand:
  14639. + nand_release(&info->mtd);
  14640. +err_set_drvdata:
  14641. + platform_set_drvdata(pdev, NULL);
  14642. +err_free_info:
  14643. + kfree(info);
  14644. +err_free_gpio_nce:
  14645. + gpio_free(RB4XX_NAND_GPIO_NCE);
  14646. +err_free_gpio_cle:
  14647. + gpio_free(RB4XX_NAND_GPIO_CLE);
  14648. +err_free_gpio_ale:
  14649. + gpio_free(RB4XX_NAND_GPIO_ALE);
  14650. +err_free_gpio_ready:
  14651. + gpio_free(RB4XX_NAND_GPIO_READY);
  14652. +err:
  14653. + return ret;
  14654. +}
  14655. +
  14656. +static int __devexit rb4xx_nand_remove(struct platform_device *pdev)
  14657. +{
  14658. + struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
  14659. +
  14660. + nand_release(&info->mtd);
  14661. + platform_set_drvdata(pdev, NULL);
  14662. + kfree(info);
  14663. + gpio_free(RB4XX_NAND_GPIO_NCE);
  14664. + gpio_free(RB4XX_NAND_GPIO_CLE);
  14665. + gpio_free(RB4XX_NAND_GPIO_ALE);
  14666. + gpio_free(RB4XX_NAND_GPIO_READY);
  14667. +
  14668. + return 0;
  14669. +}
  14670. +
  14671. +static struct platform_driver rb4xx_nand_driver = {
  14672. + .probe = rb4xx_nand_probe,
  14673. + .remove = __devexit_p(rb4xx_nand_remove),
  14674. + .driver = {
  14675. + .name = DRV_NAME,
  14676. + .owner = THIS_MODULE,
  14677. + },
  14678. +};
  14679. +
  14680. +static int __init rb4xx_nand_init(void)
  14681. +{
  14682. + return platform_driver_register(&rb4xx_nand_driver);
  14683. +}
  14684. +
  14685. +static void __exit rb4xx_nand_exit(void)
  14686. +{
  14687. + platform_driver_unregister(&rb4xx_nand_driver);
  14688. +}
  14689. +
  14690. +module_init(rb4xx_nand_init);
  14691. +module_exit(rb4xx_nand_exit);
  14692. +
  14693. +MODULE_DESCRIPTION(DRV_DESC);
  14694. +MODULE_VERSION(DRV_VERSION);
  14695. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  14696. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  14697. +MODULE_LICENSE("GPL v2");
  14698. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c
  14699. --- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100
  14700. +++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-08-24 18:17:24.000000000 +0200
  14701. @@ -0,0 +1,361 @@
  14702. +/*
  14703. + * NAND flash driver for the MikroTik RouterBOARD 750
  14704. + *
  14705. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  14706. + *
  14707. + * This program is free software; you can redistribute it and/or modify it
  14708. + * under the terms of the GNU General Public License version 2 as published
  14709. + * by the Free Software Foundation.
  14710. + */
  14711. +
  14712. +#include <linux/init.h>
  14713. +#include <linux/mtd/nand.h>
  14714. +#include <linux/mtd/mtd.h>
  14715. +#include <linux/mtd/partitions.h>
  14716. +#include <linux/platform_device.h>
  14717. +#include <linux/io.h>
  14718. +#include <linux/slab.h>
  14719. +
  14720. +#include <asm/mach-ar71xx/ar71xx.h>
  14721. +#include <asm/mach-ar71xx/mach-rb750.h>
  14722. +
  14723. +#define DRV_NAME "rb750-nand"
  14724. +#define DRV_VERSION "0.1.0"
  14725. +#define DRV_DESC "NAND flash driver for the RouterBOARD 750"
  14726. +
  14727. +#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0)
  14728. +#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE)
  14729. +#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE)
  14730. +#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE)
  14731. +#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE)
  14732. +#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY)
  14733. +#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE)
  14734. +
  14735. +#define RB750_NAND_DATA_SHIFT 1
  14736. +#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT)
  14737. +#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY)
  14738. +#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \
  14739. + RB750_NAND_NRE | RB750_NAND_NWE | \
  14740. + RB750_NAND_NCE)
  14741. +
  14742. +struct rb750_nand_info {
  14743. + struct nand_chip chip;
  14744. + struct mtd_info mtd;
  14745. +};
  14746. +
  14747. +/*
  14748. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  14749. + * will not be able to find the kernel that we load.
  14750. + */
  14751. +static struct nand_ecclayout rb750_nand_ecclayout = {
  14752. + .eccbytes = 6,
  14753. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  14754. + .oobavail = 9,
  14755. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  14756. +};
  14757. +
  14758. +static struct mtd_partition rb750_nand_partitions[] = {
  14759. + {
  14760. + .name = "booter",
  14761. + .offset = 0,
  14762. + .size = (256 * 1024),
  14763. + .mask_flags = MTD_WRITEABLE,
  14764. + }, {
  14765. + .name = "kernel",
  14766. + .offset = (256 * 1024),
  14767. + .size = (4 * 1024 * 1024) - (256 * 1024),
  14768. + }, {
  14769. + .name = "rootfs",
  14770. + .offset = MTDPART_OFS_NXTBLK,
  14771. + .size = MTDPART_SIZ_FULL,
  14772. + },
  14773. +};
  14774. +
  14775. +static void rb750_nand_write(const u8 *buf, unsigned len)
  14776. +{
  14777. + void __iomem *base = ar71xx_gpio_base;
  14778. + u32 out;
  14779. + unsigned i;
  14780. +
  14781. + /* set data lines to output mode */
  14782. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS,
  14783. + base + GPIO_REG_OE);
  14784. +
  14785. + out = __raw_readl(base + GPIO_REG_OUT);
  14786. + out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE);
  14787. + for (i = 0; i != len; i++) {
  14788. + u32 data;
  14789. +
  14790. + data = buf[i];
  14791. + data <<= RB750_NAND_DATA_SHIFT;
  14792. + data |= out;
  14793. + __raw_writel(data, base + GPIO_REG_OUT);
  14794. +
  14795. + __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT);
  14796. + /* flush write */
  14797. + __raw_readl(base + GPIO_REG_OUT);
  14798. + }
  14799. +
  14800. + /* set data lines to input mode */
  14801. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS,
  14802. + base + GPIO_REG_OE);
  14803. + /* flush write */
  14804. + __raw_readl(base + GPIO_REG_OE);
  14805. +}
  14806. +
  14807. +static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
  14808. + const u8 *verify_buf)
  14809. +{
  14810. + void __iomem *base = ar71xx_gpio_base;
  14811. + unsigned i;
  14812. +
  14813. + for (i = 0; i < len; i++) {
  14814. + u8 data;
  14815. +
  14816. + /* activate RE line */
  14817. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR);
  14818. + /* flush write */
  14819. + __raw_readl(base + GPIO_REG_CLEAR);
  14820. +
  14821. + /* read input lines */
  14822. + data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT;
  14823. +
  14824. + /* deactivate RE line */
  14825. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET);
  14826. +
  14827. + if (read_buf)
  14828. + read_buf[i] = data;
  14829. + else if (verify_buf && verify_buf[i] != data)
  14830. + return -EFAULT;
  14831. + }
  14832. +
  14833. + return 0;
  14834. +}
  14835. +
  14836. +static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
  14837. +{
  14838. + void __iomem *base = ar71xx_gpio_base;
  14839. + u32 func;
  14840. +
  14841. + func = __raw_readl(base + GPIO_REG_FUNC);
  14842. + if (chip >= 0) {
  14843. + /* disable latch */
  14844. + rb750_latch_change(RB750_LVC573_LE, 0);
  14845. +
  14846. + /* disable alternate functions */
  14847. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
  14848. + AR724X_GPIO_FUNC_SPI_EN);
  14849. +
  14850. + /* set input mode for data lines */
  14851. + __raw_writel(__raw_readl(base + GPIO_REG_OE) &
  14852. + ~RB750_NAND_INPUT_BITS,
  14853. + base + GPIO_REG_OE);
  14854. +
  14855. + /* deactivate RE and WE lines */
  14856. + __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE,
  14857. + base + GPIO_REG_SET);
  14858. + /* flush write */
  14859. + (void) __raw_readl(base + GPIO_REG_SET);
  14860. +
  14861. + /* activate CE line */
  14862. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR);
  14863. + } else {
  14864. + /* deactivate CE line */
  14865. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET);
  14866. + /* flush write */
  14867. + (void) __raw_readl(base + GPIO_REG_SET);
  14868. +
  14869. + __raw_writel(__raw_readl(base + GPIO_REG_OE) |
  14870. + RB750_NAND_IO0 | RB750_NAND_RDY,
  14871. + base + GPIO_REG_OE);
  14872. +
  14873. + /* restore alternate functions */
  14874. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
  14875. + AR724X_GPIO_FUNC_JTAG_DISABLE);
  14876. +
  14877. + /* enable latch */
  14878. + rb750_latch_change(0, RB750_LVC573_LE);
  14879. + }
  14880. +}
  14881. +
  14882. +static int rb750_nand_dev_ready(struct mtd_info *mtd)
  14883. +{
  14884. + void __iomem *base = ar71xx_gpio_base;
  14885. +
  14886. + return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY);
  14887. +}
  14888. +
  14889. +static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  14890. + unsigned int ctrl)
  14891. +{
  14892. + if (ctrl & NAND_CTRL_CHANGE) {
  14893. + void __iomem *base = ar71xx_gpio_base;
  14894. + u32 t;
  14895. +
  14896. + t = __raw_readl(base + GPIO_REG_OUT);
  14897. +
  14898. + t &= ~(RB750_NAND_CLE | RB750_NAND_ALE);
  14899. + t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0;
  14900. + t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0;
  14901. +
  14902. + __raw_writel(t, base + GPIO_REG_OUT);
  14903. + /* flush write */
  14904. + __raw_readl(base + GPIO_REG_OUT);
  14905. + }
  14906. +
  14907. + if (cmd != NAND_CMD_NONE) {
  14908. + u8 t = cmd;
  14909. + rb750_nand_write(&t, 1);
  14910. + }
  14911. +}
  14912. +
  14913. +static u8 rb750_nand_read_byte(struct mtd_info *mtd)
  14914. +{
  14915. + u8 data = 0;
  14916. + rb750_nand_read_verify(&data, 1, NULL);
  14917. + return data;
  14918. +}
  14919. +
  14920. +static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
  14921. +{
  14922. + rb750_nand_read_verify(buf, len, NULL);
  14923. +}
  14924. +
  14925. +static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  14926. +{
  14927. + rb750_nand_write(buf, len);
  14928. +}
  14929. +
  14930. +static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
  14931. +{
  14932. + return rb750_nand_read_verify(NULL, len, buf);
  14933. +}
  14934. +
  14935. +static void __init rb750_nand_gpio_init(void)
  14936. +{
  14937. + void __iomem *base = ar71xx_gpio_base;
  14938. + u32 out;
  14939. +
  14940. + out = __raw_readl(base + GPIO_REG_OUT);
  14941. +
  14942. + /* setup output levels */
  14943. + __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE,
  14944. + base + GPIO_REG_SET);
  14945. +
  14946. + __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE,
  14947. + base + GPIO_REG_CLEAR);
  14948. +
  14949. + /* setup input lines */
  14950. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS),
  14951. + base + GPIO_REG_OE);
  14952. +
  14953. + /* setup output lines */
  14954. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS,
  14955. + base + GPIO_REG_OE);
  14956. +
  14957. + rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
  14958. +}
  14959. +
  14960. +static int __init rb750_nand_probe(struct platform_device *pdev)
  14961. +{
  14962. + struct rb750_nand_info *info;
  14963. + int ret;
  14964. +
  14965. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  14966. +
  14967. + rb750_nand_gpio_init();
  14968. +
  14969. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  14970. + if (!info)
  14971. + return -ENOMEM;
  14972. +
  14973. + info->chip.priv = &info;
  14974. + info->mtd.priv = &info->chip;
  14975. + info->mtd.owner = THIS_MODULE;
  14976. +
  14977. + info->chip.select_chip = rb750_nand_select_chip;
  14978. + info->chip.cmd_ctrl = rb750_nand_cmd_ctrl;
  14979. + info->chip.dev_ready = rb750_nand_dev_ready;
  14980. + info->chip.read_byte = rb750_nand_read_byte;
  14981. + info->chip.write_buf = rb750_nand_write_buf;
  14982. + info->chip.read_buf = rb750_nand_read_buf;
  14983. + info->chip.verify_buf = rb750_nand_verify_buf;
  14984. +
  14985. + info->chip.chip_delay = 25;
  14986. + info->chip.ecc.mode = NAND_ECC_SOFT;
  14987. + info->chip.options |= NAND_NO_AUTOINCR;
  14988. +
  14989. + platform_set_drvdata(pdev, info);
  14990. +
  14991. + ret = nand_scan_ident(&info->mtd, 1);
  14992. + if (ret) {
  14993. + ret = -ENXIO;
  14994. + goto err_free_info;
  14995. + }
  14996. +
  14997. + if (info->mtd.writesize == 512)
  14998. + info->chip.ecc.layout = &rb750_nand_ecclayout;
  14999. +
  15000. + ret = nand_scan_tail(&info->mtd);
  15001. + if (ret) {
  15002. + return -ENXIO;
  15003. + goto err_set_drvdata;
  15004. + }
  15005. +
  15006. +#ifdef CONFIG_MTD_PARTITIONS
  15007. + ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions,
  15008. + ARRAY_SIZE(rb750_nand_partitions));
  15009. +#else
  15010. + ret = add_mtd_device(&info->mtd);
  15011. +#endif
  15012. + if (ret)
  15013. + goto err_release_nand;
  15014. +
  15015. + return 0;
  15016. +
  15017. +err_release_nand:
  15018. + nand_release(&info->mtd);
  15019. +err_set_drvdata:
  15020. + platform_set_drvdata(pdev, NULL);
  15021. +err_free_info:
  15022. + kfree(info);
  15023. + return ret;
  15024. +}
  15025. +
  15026. +static int __devexit rb750_nand_remove(struct platform_device *pdev)
  15027. +{
  15028. + struct rb750_nand_info *info = platform_get_drvdata(pdev);
  15029. +
  15030. + nand_release(&info->mtd);
  15031. + platform_set_drvdata(pdev, NULL);
  15032. + kfree(info);
  15033. +
  15034. + return 0;
  15035. +}
  15036. +
  15037. +static struct platform_driver rb750_nand_driver = {
  15038. + .probe = rb750_nand_probe,
  15039. + .remove = __devexit_p(rb750_nand_remove),
  15040. + .driver = {
  15041. + .name = DRV_NAME,
  15042. + .owner = THIS_MODULE,
  15043. + },
  15044. +};
  15045. +
  15046. +static int __init rb750_nand_init(void)
  15047. +{
  15048. + return platform_driver_register(&rb750_nand_driver);
  15049. +}
  15050. +
  15051. +static void __exit rb750_nand_exit(void)
  15052. +{
  15053. + platform_driver_unregister(&rb750_nand_driver);
  15054. +}
  15055. +
  15056. +module_init(rb750_nand_init);
  15057. +module_exit(rb750_nand_exit);
  15058. +
  15059. +MODULE_DESCRIPTION(DRV_DESC);
  15060. +MODULE_VERSION(DRV_VERSION);
  15061. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15062. +MODULE_LICENSE("GPL v2");
  15063. diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c
  15064. --- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100
  15065. +++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-08-24 18:17:24.000000000 +0200
  15066. @@ -0,0 +1,190 @@
  15067. +/*
  15068. + * Copyright (C) 2009 Christian Daniel <cd@maintech.de>
  15069. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15070. + *
  15071. + * This program is free software; you can redistribute it and/or modify
  15072. + * it under the terms of the GNU General Public License as published by
  15073. + * the Free Software Foundation; either version 2 of the License, or
  15074. + * (at your option) any later version.
  15075. + *
  15076. + * This program is distributed in the hope that it will be useful,
  15077. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15078. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15079. + * GNU General Public License for more details.
  15080. + *
  15081. + * You should have received a copy of the GNU General Public License
  15082. + * along with this program; if not, write to the Free Software
  15083. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15084. + *
  15085. + * TRX flash partition table.
  15086. + * Based on ar7 map by Felix Fietkau <nbd@openwrt.org>
  15087. + *
  15088. + */
  15089. +
  15090. +#include <linux/kernel.h>
  15091. +#include <linux/slab.h>
  15092. +#include <linux/vmalloc.h>
  15093. +
  15094. +#include <linux/mtd/mtd.h>
  15095. +#include <linux/mtd/partitions.h>
  15096. +
  15097. +struct cybertan_header {
  15098. + char magic[4];
  15099. + u8 res1[4];
  15100. + char fw_date[3];
  15101. + char fw_ver[3];
  15102. + char id[4];
  15103. + char hw_ver;
  15104. + char unused;
  15105. + u8 flags[2];
  15106. + u8 res2[10];
  15107. +};
  15108. +
  15109. +#define TRX_PARTS 6
  15110. +#define TRX_MAGIC 0x30524448
  15111. +#define TRX_MAX_OFFSET 3
  15112. +
  15113. +struct trx_header {
  15114. + uint32_t magic; /* "HDR0" */
  15115. + uint32_t len; /* Length of file including header */
  15116. + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
  15117. + uint32_t flag_version; /* 0:15 flags, 16:31 version */
  15118. + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
  15119. +};
  15120. +
  15121. +#define IH_MAGIC 0x27051956 /* Image Magic Number */
  15122. +#define IH_NMLEN 32 /* Image Name Length */
  15123. +
  15124. +struct uimage_header {
  15125. + uint32_t ih_magic; /* Image Header Magic Number */
  15126. + uint32_t ih_hcrc; /* Image Header CRC Checksum */
  15127. + uint32_t ih_time; /* Image Creation Timestamp */
  15128. + uint32_t ih_size; /* Image Data Size */
  15129. + uint32_t ih_load; /* Data» Load Address */
  15130. + uint32_t ih_ep; /* Entry Point Address */
  15131. + uint32_t ih_dcrc; /* Image Data CRC Checksum */
  15132. + uint8_t ih_os; /* Operating System */
  15133. + uint8_t ih_arch; /* CPU architecture */
  15134. + uint8_t ih_type; /* Image Type */
  15135. + uint8_t ih_comp; /* Compression Type */
  15136. + uint8_t ih_name[IH_NMLEN]; /* Image Name */
  15137. +};
  15138. +
  15139. +struct wrt160nl_header {
  15140. + struct cybertan_header cybertan;
  15141. + struct trx_header trx;
  15142. + struct uimage_header uimage;
  15143. +} __attribute__ ((packed));
  15144. +
  15145. +static struct mtd_partition trx_parts[TRX_PARTS];
  15146. +
  15147. +#define WRT160NL_UBOOT_LEN 0x40000
  15148. +#define WRT160NL_ART_LEN 0x10000
  15149. +#define WRT160NL_NVRAM_LEN 0x10000
  15150. +
  15151. +static int wrt160nl_parse_partitions(struct mtd_info *master,
  15152. + struct mtd_partition **pparts,
  15153. + unsigned long origin)
  15154. +{
  15155. + struct wrt160nl_header *header;
  15156. + struct trx_header *theader;
  15157. + struct uimage_header *uheader;
  15158. + size_t retlen;
  15159. + unsigned int kernel_len;
  15160. + unsigned int uboot_len = max(master->erasesize, WRT160NL_UBOOT_LEN);
  15161. + unsigned int nvram_len = max(master->erasesize, WRT160NL_NVRAM_LEN);
  15162. + unsigned int art_len = max(master->erasesize, WRT160NL_ART_LEN);
  15163. + int ret;
  15164. +
  15165. + header = vmalloc(sizeof(*header));
  15166. + if (!header) {
  15167. + return -ENOMEM;
  15168. + goto out;
  15169. + }
  15170. +
  15171. + ret = master->read(master, uboot_len, sizeof(*header),
  15172. + &retlen, (void *) header);
  15173. + if (ret)
  15174. + goto free_hdr;
  15175. +
  15176. + if (retlen != sizeof(*header)) {
  15177. + ret = -EIO;
  15178. + goto free_hdr;
  15179. + }
  15180. +
  15181. + if (strncmp(header->cybertan.magic, "NL16", 4) != 0) {
  15182. + printk(KERN_NOTICE "%s: no WRT160NL signature found\n",
  15183. + master->name);
  15184. + goto free_hdr;
  15185. + }
  15186. +
  15187. + theader = &header->trx;
  15188. + if (le32_to_cpu(theader->magic) != TRX_MAGIC) {
  15189. + printk(KERN_NOTICE "%s: no TRX header found\n", master->name);
  15190. + goto free_hdr;
  15191. + }
  15192. +
  15193. + uheader = &header->uimage;
  15194. + if (uheader->ih_magic != IH_MAGIC) {
  15195. + printk(KERN_NOTICE "%s: no uImage found\n", master->name);
  15196. + goto free_hdr;
  15197. + }
  15198. +
  15199. + kernel_len = le32_to_cpu(theader->offsets[1]) +
  15200. + sizeof(struct cybertan_header);
  15201. +
  15202. + trx_parts[0].name = "u-boot";
  15203. + trx_parts[0].offset = 0;
  15204. + trx_parts[0].size = uboot_len;
  15205. + trx_parts[0].mask_flags = MTD_WRITEABLE;
  15206. +
  15207. + trx_parts[1].name = "kernel";
  15208. + trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size;
  15209. + trx_parts[1].size = kernel_len;
  15210. + trx_parts[1].mask_flags = 0;
  15211. +
  15212. + trx_parts[2].name = "rootfs";
  15213. + trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size;
  15214. + trx_parts[2].size = master->size - uboot_len - nvram_len - art_len -
  15215. + trx_parts[1].size;
  15216. + trx_parts[2].mask_flags = 0;
  15217. +
  15218. + trx_parts[3].name = "nvram";
  15219. + trx_parts[3].offset = master->size - nvram_len - art_len;
  15220. + trx_parts[3].size = nvram_len;
  15221. + trx_parts[3].mask_flags = MTD_WRITEABLE;
  15222. +
  15223. + trx_parts[4].name = "art";
  15224. + trx_parts[4].offset = master->size - art_len;
  15225. + trx_parts[4].size = art_len;
  15226. + trx_parts[4].mask_flags = MTD_WRITEABLE;
  15227. +
  15228. + trx_parts[5].name = "firmware";
  15229. + trx_parts[5].offset = uboot_len;
  15230. + trx_parts[5].size = master->size - uboot_len - nvram_len - art_len;
  15231. + trx_parts[5].mask_flags = 0;
  15232. +
  15233. + *pparts = trx_parts;
  15234. + ret = TRX_PARTS;
  15235. +
  15236. +free_hdr:
  15237. + vfree(header);
  15238. +out:
  15239. + return ret;
  15240. +}
  15241. +
  15242. +static struct mtd_part_parser wrt160nl_parser = {
  15243. + .owner = THIS_MODULE,
  15244. + .parse_fn = wrt160nl_parse_partitions,
  15245. + .name = "wrt160nl",
  15246. +};
  15247. +
  15248. +static int __init wrt160nl_parser_init(void)
  15249. +{
  15250. + return register_mtd_parser(&wrt160nl_parser);
  15251. +}
  15252. +
  15253. +module_init(wrt160nl_parser_init);
  15254. +
  15255. +MODULE_LICENSE("GPL");
  15256. +MODULE_AUTHOR("Christian Daniel <cd@maintech.de>");
  15257. diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig
  15258. --- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200
  15259. +++ linux-2.6.39/drivers/net/Kconfig 2011-08-24 18:17:24.000000000 +0200
  15260. @@ -2071,6 +2071,8 @@
  15261. The safe and default value for this is N.
  15262. +source drivers/net/ag71xx/Kconfig
  15263. +
  15264. config DL2K
  15265. tristate "DL2000/TC902x-based Gigabit Ethernet support"
  15266. depends on PCI
  15267. diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile
  15268. --- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200
  15269. +++ linux-2.6.39/drivers/net/Makefile 2011-08-24 18:17:24.000000000 +0200
  15270. @@ -112,6 +112,7 @@
  15271. # end link order section
  15272. #
  15273. +obj-$(CONFIG_AG71XX) += ag71xx/
  15274. obj-$(CONFIG_SUNDANCE) += sundance.o
  15275. obj-$(CONFIG_HAMACHI) += hamachi.o
  15276. obj-$(CONFIG_NET) += Space.o loopback.o
  15277. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig
  15278. --- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  15279. +++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-08-24 18:17:24.000000000 +0200
  15280. @@ -0,0 +1,33 @@
  15281. +config AG71XX
  15282. + tristate "Atheros AR71xx built-in ethernet mac support"
  15283. + depends on ATHEROS_AR71XX
  15284. + select PHYLIB
  15285. + help
  15286. + If you wish to compile a kernel for AR71xx/91xx and enable
  15287. + ethernet support, then you should always answer Y to this.
  15288. +
  15289. +if AG71XX
  15290. +
  15291. +config AG71XX_DEBUG
  15292. + bool "Atheros AR71xx built-in ethernet driver debugging"
  15293. + default n
  15294. + help
  15295. + Atheros AR71xx built-in ethernet driver debugging messages.
  15296. +
  15297. +config AG71XX_DEBUG_FS
  15298. + bool "Atheros AR71xx built-in ethernet driver debugfs support"
  15299. + depends on DEBUG_FS
  15300. + default n
  15301. + help
  15302. + Say Y, if you need access to various statistics provided by
  15303. + the ag71xx driver.
  15304. +
  15305. +config AG71XX_AR8216_SUPPORT
  15306. + bool "special support for the Atheros AR8216 switch"
  15307. + default n
  15308. + default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU
  15309. + help
  15310. + Say 'y' here if you want to enable special support for the
  15311. + Atheros AR8216 switch found on some boards.
  15312. +
  15313. +endif
  15314. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile
  15315. --- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  15316. +++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-08-24 18:17:24.000000000 +0200
  15317. @@ -0,0 +1,15 @@
  15318. +#
  15319. +# Makefile for the Atheros AR71xx built-in ethernet macs
  15320. +#
  15321. +
  15322. +ag71xx-y += ag71xx_main.o
  15323. +ag71xx-y += ag71xx_ethtool.o
  15324. +ag71xx-y += ag71xx_phy.o
  15325. +ag71xx-y += ag71xx_mdio.o
  15326. +ag71xx-y += ag71xx_ar7240.o
  15327. +
  15328. +ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o
  15329. +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o
  15330. +
  15331. +obj-$(CONFIG_AG71XX) += ag71xx.o
  15332. +
  15333. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h
  15334. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100
  15335. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-08-24 18:17:24.000000000 +0200
  15336. @@ -0,0 +1,518 @@
  15337. +/*
  15338. + * Atheros AR71xx built-in ethernet mac driver
  15339. + *
  15340. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  15341. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  15342. + *
  15343. + * Based on Atheros' AG7100 driver
  15344. + *
  15345. + * This program is free software; you can redistribute it and/or modify it
  15346. + * under the terms of the GNU General Public License version 2 as published
  15347. + * by the Free Software Foundation.
  15348. + */
  15349. +
  15350. +#ifndef __AG71XX_H
  15351. +#define __AG71XX_H
  15352. +
  15353. +#include <linux/kernel.h>
  15354. +#include <linux/version.h>
  15355. +#include <linux/module.h>
  15356. +#include <linux/init.h>
  15357. +#include <linux/types.h>
  15358. +#include <linux/random.h>
  15359. +#include <linux/spinlock.h>
  15360. +#include <linux/interrupt.h>
  15361. +#include <linux/platform_device.h>
  15362. +#include <linux/ethtool.h>
  15363. +#include <linux/etherdevice.h>
  15364. +#include <linux/if_vlan.h>
  15365. +#include <linux/phy.h>
  15366. +#include <linux/skbuff.h>
  15367. +#include <linux/dma-mapping.h>
  15368. +#include <linux/workqueue.h>
  15369. +
  15370. +#include <linux/bitops.h>
  15371. +
  15372. +#include <asm/mach-ar71xx/ar71xx.h>
  15373. +#include <asm/mach-ar71xx/platform.h>
  15374. +
  15375. +#define AG71XX_DRV_NAME "ag71xx"
  15376. +#define AG71XX_DRV_VERSION "0.5.35"
  15377. +
  15378. +#define AG71XX_NAPI_WEIGHT 64
  15379. +#define AG71XX_OOM_REFILL (1 + HZ/10)
  15380. +
  15381. +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
  15382. +#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
  15383. +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
  15384. +
  15385. +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
  15386. +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
  15387. +
  15388. +#define AG71XX_TX_MTU_LEN 1540
  15389. +#define AG71XX_RX_PKT_RESERVE 64
  15390. +#define AG71XX_RX_PKT_SIZE \
  15391. + (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
  15392. +
  15393. +#define AG71XX_TX_RING_SIZE_DEFAULT 64
  15394. +#define AG71XX_RX_RING_SIZE_DEFAULT 128
  15395. +
  15396. +#define AG71XX_TX_RING_SIZE_MAX 256
  15397. +#define AG71XX_RX_RING_SIZE_MAX 256
  15398. +
  15399. +#ifdef CONFIG_AG71XX_DEBUG
  15400. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  15401. +#else
  15402. +#define DBG(fmt, args...) do {} while (0)
  15403. +#endif
  15404. +
  15405. +#define ag71xx_assert(_cond) \
  15406. +do { \
  15407. + if (_cond) \
  15408. + break; \
  15409. + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \
  15410. + BUG(); \
  15411. +} while (0)
  15412. +
  15413. +struct ag71xx_desc {
  15414. + u32 data;
  15415. + u32 ctrl;
  15416. +#define DESC_EMPTY BIT(31)
  15417. +#define DESC_MORE BIT(24)
  15418. +#define DESC_PKTLEN_M 0xfff
  15419. + u32 next;
  15420. + u32 pad;
  15421. +} __attribute__((aligned(4)));
  15422. +
  15423. +struct ag71xx_buf {
  15424. + struct sk_buff *skb;
  15425. + struct ag71xx_desc *desc;
  15426. + dma_addr_t dma_addr;
  15427. + unsigned long timestamp;
  15428. +};
  15429. +
  15430. +struct ag71xx_ring {
  15431. + struct ag71xx_buf *buf;
  15432. + u8 *descs_cpu;
  15433. + dma_addr_t descs_dma;
  15434. + unsigned int desc_size;
  15435. + unsigned int curr;
  15436. + unsigned int dirty;
  15437. + unsigned int size;
  15438. +};
  15439. +
  15440. +struct ag71xx_mdio {
  15441. + struct mii_bus *mii_bus;
  15442. + int mii_irq[PHY_MAX_ADDR];
  15443. + void __iomem *mdio_base;
  15444. + struct ag71xx_mdio_platform_data *pdata;
  15445. +};
  15446. +
  15447. +struct ag71xx_int_stats {
  15448. + unsigned long rx_pr;
  15449. + unsigned long rx_be;
  15450. + unsigned long rx_of;
  15451. + unsigned long tx_ps;
  15452. + unsigned long tx_be;
  15453. + unsigned long tx_ur;
  15454. + unsigned long total;
  15455. +};
  15456. +
  15457. +struct ag71xx_napi_stats {
  15458. + unsigned long napi_calls;
  15459. + unsigned long rx_count;
  15460. + unsigned long rx_packets;
  15461. + unsigned long rx_packets_max;
  15462. + unsigned long tx_count;
  15463. + unsigned long tx_packets;
  15464. + unsigned long tx_packets_max;
  15465. +
  15466. + unsigned long rx[AG71XX_NAPI_WEIGHT + 1];
  15467. + unsigned long tx[AG71XX_NAPI_WEIGHT + 1];
  15468. +};
  15469. +
  15470. +struct ag71xx_debug {
  15471. + struct dentry *debugfs_dir;
  15472. +
  15473. + struct ag71xx_int_stats int_stats;
  15474. + struct ag71xx_napi_stats napi_stats;
  15475. +};
  15476. +
  15477. +struct ag71xx {
  15478. + void __iomem *mac_base;
  15479. + void __iomem *mii_ctrl;
  15480. +
  15481. + spinlock_t lock;
  15482. + struct platform_device *pdev;
  15483. + struct net_device *dev;
  15484. + struct napi_struct napi;
  15485. + u32 msg_enable;
  15486. +
  15487. + struct ag71xx_desc *stop_desc;
  15488. + dma_addr_t stop_desc_dma;
  15489. +
  15490. + struct ag71xx_ring rx_ring;
  15491. + struct ag71xx_ring tx_ring;
  15492. +
  15493. + struct mii_bus *mii_bus;
  15494. + struct phy_device *phy_dev;
  15495. + void *phy_priv;
  15496. +
  15497. + unsigned int link;
  15498. + unsigned int speed;
  15499. + int duplex;
  15500. +
  15501. + struct work_struct restart_work;
  15502. + struct delayed_work link_work;
  15503. + struct timer_list oom_timer;
  15504. +
  15505. +#ifdef CONFIG_AG71XX_DEBUG_FS
  15506. + struct ag71xx_debug debug;
  15507. +#endif
  15508. +};
  15509. +
  15510. +extern struct ethtool_ops ag71xx_ethtool_ops;
  15511. +void ag71xx_link_adjust(struct ag71xx *ag);
  15512. +
  15513. +int ag71xx_mdio_driver_init(void) __init;
  15514. +void ag71xx_mdio_driver_exit(void);
  15515. +
  15516. +int ag71xx_phy_connect(struct ag71xx *ag);
  15517. +void ag71xx_phy_disconnect(struct ag71xx *ag);
  15518. +void ag71xx_phy_start(struct ag71xx *ag);
  15519. +void ag71xx_phy_stop(struct ag71xx *ag);
  15520. +
  15521. +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
  15522. +{
  15523. + return ag->pdev->dev.platform_data;
  15524. +}
  15525. +
  15526. +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
  15527. +{
  15528. + return (desc->ctrl & DESC_EMPTY) != 0;
  15529. +}
  15530. +
  15531. +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
  15532. +{
  15533. + return desc->ctrl & DESC_PKTLEN_M;
  15534. +}
  15535. +
  15536. +/* Register offsets */
  15537. +#define AG71XX_REG_MAC_CFG1 0x0000
  15538. +#define AG71XX_REG_MAC_CFG2 0x0004
  15539. +#define AG71XX_REG_MAC_IPG 0x0008
  15540. +#define AG71XX_REG_MAC_HDX 0x000c
  15541. +#define AG71XX_REG_MAC_MFL 0x0010
  15542. +#define AG71XX_REG_MII_CFG 0x0020
  15543. +#define AG71XX_REG_MII_CMD 0x0024
  15544. +#define AG71XX_REG_MII_ADDR 0x0028
  15545. +#define AG71XX_REG_MII_CTRL 0x002c
  15546. +#define AG71XX_REG_MII_STATUS 0x0030
  15547. +#define AG71XX_REG_MII_IND 0x0034
  15548. +#define AG71XX_REG_MAC_IFCTL 0x0038
  15549. +#define AG71XX_REG_MAC_ADDR1 0x0040
  15550. +#define AG71XX_REG_MAC_ADDR2 0x0044
  15551. +#define AG71XX_REG_FIFO_CFG0 0x0048
  15552. +#define AG71XX_REG_FIFO_CFG1 0x004c
  15553. +#define AG71XX_REG_FIFO_CFG2 0x0050
  15554. +#define AG71XX_REG_FIFO_CFG3 0x0054
  15555. +#define AG71XX_REG_FIFO_CFG4 0x0058
  15556. +#define AG71XX_REG_FIFO_CFG5 0x005c
  15557. +#define AG71XX_REG_FIFO_RAM0 0x0060
  15558. +#define AG71XX_REG_FIFO_RAM1 0x0064
  15559. +#define AG71XX_REG_FIFO_RAM2 0x0068
  15560. +#define AG71XX_REG_FIFO_RAM3 0x006c
  15561. +#define AG71XX_REG_FIFO_RAM4 0x0070
  15562. +#define AG71XX_REG_FIFO_RAM5 0x0074
  15563. +#define AG71XX_REG_FIFO_RAM6 0x0078
  15564. +#define AG71XX_REG_FIFO_RAM7 0x007c
  15565. +
  15566. +#define AG71XX_REG_TX_CTRL 0x0180
  15567. +#define AG71XX_REG_TX_DESC 0x0184
  15568. +#define AG71XX_REG_TX_STATUS 0x0188
  15569. +#define AG71XX_REG_RX_CTRL 0x018c
  15570. +#define AG71XX_REG_RX_DESC 0x0190
  15571. +#define AG71XX_REG_RX_STATUS 0x0194
  15572. +#define AG71XX_REG_INT_ENABLE 0x0198
  15573. +#define AG71XX_REG_INT_STATUS 0x019c
  15574. +
  15575. +#define AG71XX_REG_FIFO_DEPTH 0x01a8
  15576. +#define AG71XX_REG_RX_SM 0x01b0
  15577. +#define AG71XX_REG_TX_SM 0x01b4
  15578. +
  15579. +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
  15580. +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
  15581. +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
  15582. +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
  15583. +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
  15584. +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
  15585. +#define MAC_CFG1_LB BIT(8) /* Loopback mode */
  15586. +#define MAC_CFG1_SR BIT(31) /* Soft Reset */
  15587. +
  15588. +#define MAC_CFG2_FDX BIT(0)
  15589. +#define MAC_CFG2_CRC_EN BIT(1)
  15590. +#define MAC_CFG2_PAD_CRC_EN BIT(2)
  15591. +#define MAC_CFG2_LEN_CHECK BIT(4)
  15592. +#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
  15593. +#define MAC_CFG2_IF_1000 BIT(9)
  15594. +#define MAC_CFG2_IF_10_100 BIT(8)
  15595. +
  15596. +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
  15597. +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
  15598. +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
  15599. +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
  15600. +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
  15601. +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
  15602. + | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
  15603. +
  15604. +#define FIFO_CFG0_ENABLE_SHIFT 8
  15605. +
  15606. +#define FIFO_CFG4_DE BIT(0) /* Drop Event */
  15607. +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
  15608. +#define FIFO_CFG4_FC BIT(2) /* False Carrier */
  15609. +#define FIFO_CFG4_CE BIT(3) /* Code Error */
  15610. +#define FIFO_CFG4_CR BIT(4) /* CRC error */
  15611. +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
  15612. +#define FIFO_CFG4_LO BIT(6) /* Length out of range */
  15613. +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
  15614. +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
  15615. +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
  15616. +#define FIFO_CFG4_DR BIT(10) /* Dribble */
  15617. +#define FIFO_CFG4_LE BIT(11) /* Long Event */
  15618. +#define FIFO_CFG4_CF BIT(12) /* Control Frame */
  15619. +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
  15620. +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
  15621. +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
  15622. +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
  15623. +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
  15624. +
  15625. +#define FIFO_CFG5_DE BIT(0) /* Drop Event */
  15626. +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
  15627. +#define FIFO_CFG5_FC BIT(2) /* False Carrier */
  15628. +#define FIFO_CFG5_CE BIT(3) /* Code Error */
  15629. +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
  15630. +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
  15631. +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
  15632. +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
  15633. +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
  15634. +#define FIFO_CFG5_DR BIT(9) /* Dribble */
  15635. +#define FIFO_CFG5_CF BIT(10) /* Control Frame */
  15636. +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
  15637. +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
  15638. +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
  15639. +#define FIFO_CFG5_LE BIT(14) /* Long Event */
  15640. +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
  15641. +#define FIFO_CFG5_16 BIT(16) /* unknown */
  15642. +#define FIFO_CFG5_17 BIT(17) /* unknown */
  15643. +#define FIFO_CFG5_SF BIT(18) /* Short Frame */
  15644. +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
  15645. +
  15646. +#define AG71XX_INT_TX_PS BIT(0)
  15647. +#define AG71XX_INT_TX_UR BIT(1)
  15648. +#define AG71XX_INT_TX_BE BIT(3)
  15649. +#define AG71XX_INT_RX_PR BIT(4)
  15650. +#define AG71XX_INT_RX_OF BIT(6)
  15651. +#define AG71XX_INT_RX_BE BIT(7)
  15652. +
  15653. +#define MAC_IFCTL_SPEED BIT(16)
  15654. +
  15655. +#define MII_CFG_CLK_DIV_4 0
  15656. +#define MII_CFG_CLK_DIV_6 2
  15657. +#define MII_CFG_CLK_DIV_8 3
  15658. +#define MII_CFG_CLK_DIV_10 4
  15659. +#define MII_CFG_CLK_DIV_14 5
  15660. +#define MII_CFG_CLK_DIV_20 6
  15661. +#define MII_CFG_CLK_DIV_28 7
  15662. +#define MII_CFG_RESET BIT(31)
  15663. +
  15664. +#define MII_CMD_WRITE 0x0
  15665. +#define MII_CMD_READ 0x1
  15666. +#define MII_ADDR_SHIFT 8
  15667. +#define MII_IND_BUSY BIT(0)
  15668. +#define MII_IND_INVALID BIT(2)
  15669. +
  15670. +#define TX_CTRL_TXE BIT(0) /* Tx Enable */
  15671. +
  15672. +#define TX_STATUS_PS BIT(0) /* Packet Sent */
  15673. +#define TX_STATUS_UR BIT(1) /* Tx Underrun */
  15674. +#define TX_STATUS_BE BIT(3) /* Bus Error */
  15675. +
  15676. +#define RX_CTRL_RXE BIT(0) /* Rx Enable */
  15677. +
  15678. +#define RX_STATUS_PR BIT(0) /* Packet Received */
  15679. +#define RX_STATUS_OF BIT(2) /* Rx Overflow */
  15680. +#define RX_STATUS_BE BIT(3) /* Bus Error */
  15681. +
  15682. +#define MII_CTRL_IF_MASK 3
  15683. +#define MII_CTRL_SPEED_SHIFT 4
  15684. +#define MII_CTRL_SPEED_MASK 3
  15685. +#define MII_CTRL_SPEED_10 0
  15686. +#define MII_CTRL_SPEED_100 1
  15687. +#define MII_CTRL_SPEED_1000 2
  15688. +
  15689. +static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
  15690. +{
  15691. + switch (reg) {
  15692. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  15693. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  15694. + case AG71XX_REG_MII_CFG:
  15695. + break;
  15696. +
  15697. + default:
  15698. + BUG();
  15699. + }
  15700. +}
  15701. +
  15702. +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
  15703. +{
  15704. + ag71xx_check_reg_offset(ag, reg);
  15705. +
  15706. + __raw_writel(value, ag->mac_base + reg);
  15707. + /* flush write */
  15708. + (void) __raw_readl(ag->mac_base + reg);
  15709. +}
  15710. +
  15711. +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
  15712. +{
  15713. + ag71xx_check_reg_offset(ag, reg);
  15714. +
  15715. + return __raw_readl(ag->mac_base + reg);
  15716. +}
  15717. +
  15718. +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
  15719. +{
  15720. + void __iomem *r;
  15721. +
  15722. + ag71xx_check_reg_offset(ag, reg);
  15723. +
  15724. + r = ag->mac_base + reg;
  15725. + __raw_writel(__raw_readl(r) | mask, r);
  15726. + /* flush write */
  15727. + (void)__raw_readl(r);
  15728. +}
  15729. +
  15730. +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
  15731. +{
  15732. + void __iomem *r;
  15733. +
  15734. + ag71xx_check_reg_offset(ag, reg);
  15735. +
  15736. + r = ag->mac_base + reg;
  15737. + __raw_writel(__raw_readl(r) & ~mask, r);
  15738. + /* flush write */
  15739. + (void) __raw_readl(r);
  15740. +}
  15741. +
  15742. +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
  15743. +{
  15744. + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
  15745. +}
  15746. +
  15747. +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
  15748. +{
  15749. + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
  15750. +}
  15751. +
  15752. +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
  15753. +{
  15754. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  15755. +
  15756. + if (pdata->is_ar724x)
  15757. + return;
  15758. +
  15759. + __raw_writel(value, ag->mii_ctrl);
  15760. +
  15761. + /* flush write */
  15762. + __raw_readl(ag->mii_ctrl);
  15763. +}
  15764. +
  15765. +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
  15766. +{
  15767. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  15768. +
  15769. + if (pdata->is_ar724x)
  15770. + return 0xffffffff;
  15771. +
  15772. + return __raw_readl(ag->mii_ctrl);
  15773. +}
  15774. +
  15775. +static inline void ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
  15776. + unsigned int mii_if)
  15777. +{
  15778. + u32 t;
  15779. +
  15780. + t = ag71xx_mii_ctrl_rr(ag);
  15781. + t &= ~(MII_CTRL_IF_MASK);
  15782. + t |= (mii_if & MII_CTRL_IF_MASK);
  15783. + ag71xx_mii_ctrl_wr(ag, t);
  15784. +}
  15785. +
  15786. +static inline void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
  15787. + unsigned int speed)
  15788. +{
  15789. + u32 t;
  15790. +
  15791. + t = ag71xx_mii_ctrl_rr(ag);
  15792. + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
  15793. + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
  15794. + ag71xx_mii_ctrl_wr(ag, t);
  15795. +}
  15796. +
  15797. +#ifdef CONFIG_AG71XX_AR8216_SUPPORT
  15798. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  15799. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  15800. + int pktlen);
  15801. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  15802. +{
  15803. + return ag71xx_get_pdata(ag)->has_ar8216;
  15804. +}
  15805. +#else
  15806. +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
  15807. + struct sk_buff *skb)
  15808. +{
  15809. +}
  15810. +
  15811. +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  15812. + struct sk_buff *skb,
  15813. + int pktlen)
  15814. +{
  15815. + return 0;
  15816. +}
  15817. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  15818. +{
  15819. + return 0;
  15820. +}
  15821. +#endif
  15822. +
  15823. +#ifdef CONFIG_AG71XX_DEBUG_FS
  15824. +int ag71xx_debugfs_root_init(void);
  15825. +void ag71xx_debugfs_root_exit(void);
  15826. +int ag71xx_debugfs_init(struct ag71xx *ag);
  15827. +void ag71xx_debugfs_exit(struct ag71xx *ag);
  15828. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status);
  15829. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx);
  15830. +#else
  15831. +static inline int ag71xx_debugfs_root_init(void) { return 0; }
  15832. +static inline void ag71xx_debugfs_root_exit(void) {}
  15833. +static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; }
  15834. +static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {}
  15835. +static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
  15836. + u32 status) {}
  15837. +static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
  15838. + int rx, int tx) {}
  15839. +#endif /* CONFIG_AG71XX_DEBUG_FS */
  15840. +
  15841. +void ag71xx_ar7240_start(struct ag71xx *ag);
  15842. +void ag71xx_ar7240_stop(struct ag71xx *ag);
  15843. +int ag71xx_ar7240_init(struct ag71xx *ag);
  15844. +void ag71xx_ar7240_cleanup(struct ag71xx *ag);
  15845. +
  15846. +int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg);
  15847. +void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val);
  15848. +
  15849. +u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr,
  15850. + unsigned reg_addr);
  15851. +int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr,
  15852. + unsigned reg_addr, u16 reg_val);
  15853. +
  15854. +#endif /* _AG71XX_H */
  15855. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c
  15856. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c 1970-01-01 01:00:00.000000000 +0100
  15857. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c 2011-08-24 18:17:24.000000000 +0200
  15858. @@ -0,0 +1,913 @@
  15859. +/*
  15860. + * Driver for the built-in ethernet switch of the Atheros AR7240 SoC
  15861. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  15862. + * Copyright (c) 2010 Felix Fietkau <nbd@openwrt.org>
  15863. + *
  15864. + * This program is free software; you can redistribute it and/or modify it
  15865. + * under the terms of the GNU General Public License version 2 as published
  15866. + * by the Free Software Foundation.
  15867. + *
  15868. + */
  15869. +
  15870. +#include <linux/etherdevice.h>
  15871. +#include <linux/list.h>
  15872. +#include <linux/netdevice.h>
  15873. +#include <linux/phy.h>
  15874. +#include <linux/mii.h>
  15875. +#include <linux/bitops.h>
  15876. +#include <linux/switch.h>
  15877. +#include "ag71xx.h"
  15878. +
  15879. +#define BITM(_count) (BIT(_count) - 1)
  15880. +#define BITS(_shift, _count) (BITM(_count) << _shift)
  15881. +
  15882. +#define AR7240_REG_MASK_CTRL 0x00
  15883. +#define AR7240_MASK_CTRL_REVISION_M BITM(8)
  15884. +#define AR7240_MASK_CTRL_VERSION_M BITM(8)
  15885. +#define AR7240_MASK_CTRL_VERSION_S 8
  15886. +#define AR7240_MASK_CTRL_SOFT_RESET BIT(31)
  15887. +
  15888. +#define AR7240_REG_MAC_ADDR0 0x20
  15889. +#define AR7240_REG_MAC_ADDR1 0x24
  15890. +
  15891. +#define AR7240_REG_FLOOD_MASK 0x2c
  15892. +#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26)
  15893. +
  15894. +#define AR7240_REG_GLOBAL_CTRL 0x30
  15895. +#define AR7240_GLOBAL_CTRL_MTU_M BITM(12)
  15896. +
  15897. +#define AR7240_REG_VTU 0x0040
  15898. +#define AR7240_VTU_OP BITM(3)
  15899. +#define AR7240_VTU_OP_NOOP 0x0
  15900. +#define AR7240_VTU_OP_FLUSH 0x1
  15901. +#define AR7240_VTU_OP_LOAD 0x2
  15902. +#define AR7240_VTU_OP_PURGE 0x3
  15903. +#define AR7240_VTU_OP_REMOVE_PORT 0x4
  15904. +#define AR7240_VTU_ACTIVE BIT(3)
  15905. +#define AR7240_VTU_FULL BIT(4)
  15906. +#define AR7240_VTU_PORT BITS(8, 4)
  15907. +#define AR7240_VTU_PORT_S 8
  15908. +#define AR7240_VTU_VID BITS(16, 12)
  15909. +#define AR7240_VTU_VID_S 16
  15910. +#define AR7240_VTU_PRIO BITS(28, 3)
  15911. +#define AR7240_VTU_PRIO_S 28
  15912. +#define AR7240_VTU_PRIO_EN BIT(31)
  15913. +
  15914. +#define AR7240_REG_VTU_DATA 0x0044
  15915. +#define AR7240_VTUDATA_MEMBER BITS(0, 10)
  15916. +#define AR7240_VTUDATA_VALID BIT(11)
  15917. +
  15918. +#define AR7240_REG_ATU 0x50
  15919. +#define AR7240_ATU_FLUSH_ALL 0x1
  15920. +
  15921. +#define AR7240_REG_AT_CTRL 0x5c
  15922. +#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15)
  15923. +#define AR7240_AT_CTRL_AGE_EN BIT(17)
  15924. +#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18)
  15925. +#define AR7240_AT_CTRL_ARP_EN BIT(20)
  15926. +
  15927. +#define AR7240_REG_TAG_PRIORITY 0x70
  15928. +
  15929. +#define AR7240_REG_SERVICE_TAG 0x74
  15930. +#define AR7240_SERVICE_TAG_M BITM(16)
  15931. +
  15932. +#define AR7240_REG_CPU_PORT 0x78
  15933. +#define AR7240_MIRROR_PORT_S 4
  15934. +#define AR7240_CPU_PORT_EN BIT(8)
  15935. +
  15936. +#define AR7240_REG_MIB_FUNCTION0 0x80
  15937. +#define AR7240_MIB_TIMER_M BITM(16)
  15938. +#define AR7240_MIB_AT_HALF_EN BIT(16)
  15939. +#define AR7240_MIB_BUSY BIT(17)
  15940. +#define AR7240_MIB_FUNC_S 24
  15941. +#define AR7240_MIB_FUNC_NO_OP 0x0
  15942. +#define AR7240_MIB_FUNC_FLUSH 0x1
  15943. +#define AR7240_MIB_FUNC_CAPTURE 0x3
  15944. +
  15945. +#define AR7240_REG_MDIO_CTRL 0x98
  15946. +#define AR7240_MDIO_CTRL_DATA_M BITM(16)
  15947. +#define AR7240_MDIO_CTRL_REG_ADDR_S 16
  15948. +#define AR7240_MDIO_CTRL_PHY_ADDR_S 21
  15949. +#define AR7240_MDIO_CTRL_CMD_WRITE 0
  15950. +#define AR7240_MDIO_CTRL_CMD_READ BIT(27)
  15951. +#define AR7240_MDIO_CTRL_MASTER_EN BIT(30)
  15952. +#define AR7240_MDIO_CTRL_BUSY BIT(31)
  15953. +
  15954. +#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100)
  15955. +
  15956. +#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00)
  15957. +#define AR7240_PORT_STATUS_SPEED_M BITM(2)
  15958. +#define AR7240_PORT_STATUS_SPEED_10 0
  15959. +#define AR7240_PORT_STATUS_SPEED_100 1
  15960. +#define AR7240_PORT_STATUS_SPEED_1000 2
  15961. +#define AR7240_PORT_STATUS_TXMAC BIT(2)
  15962. +#define AR7240_PORT_STATUS_RXMAC BIT(3)
  15963. +#define AR7240_PORT_STATUS_TXFLOW BIT(4)
  15964. +#define AR7240_PORT_STATUS_RXFLOW BIT(5)
  15965. +#define AR7240_PORT_STATUS_DUPLEX BIT(6)
  15966. +#define AR7240_PORT_STATUS_LINK_UP BIT(8)
  15967. +#define AR7240_PORT_STATUS_LINK_AUTO BIT(9)
  15968. +#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10)
  15969. +
  15970. +#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04)
  15971. +#define AR7240_PORT_CTRL_STATE_M BITM(3)
  15972. +#define AR7240_PORT_CTRL_STATE_DISABLED 0
  15973. +#define AR7240_PORT_CTRL_STATE_BLOCK 1
  15974. +#define AR7240_PORT_CTRL_STATE_LISTEN 2
  15975. +#define AR7240_PORT_CTRL_STATE_LEARN 3
  15976. +#define AR7240_PORT_CTRL_STATE_FORWARD 4
  15977. +#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7)
  15978. +#define AR7240_PORT_CTRL_VLAN_MODE_S 8
  15979. +#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0
  15980. +#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1
  15981. +#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2
  15982. +#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3
  15983. +#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10)
  15984. +#define AR7240_PORT_CTRL_HEADER BIT(11)
  15985. +#define AR7240_PORT_CTRL_MAC_LOOP BIT(12)
  15986. +#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13)
  15987. +#define AR7240_PORT_CTRL_LEARN BIT(14)
  15988. +#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15)
  15989. +#define AR7240_PORT_CTRL_MIRROR_TX BIT(16)
  15990. +#define AR7240_PORT_CTRL_MIRROR_RX BIT(17)
  15991. +
  15992. +#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08)
  15993. +
  15994. +#define AR7240_PORT_VLAN_DEFAULT_ID_S 0
  15995. +#define AR7240_PORT_VLAN_DEST_PORTS_S 16
  15996. +#define AR7240_PORT_VLAN_MODE_S 30
  15997. +#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0
  15998. +#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1
  15999. +#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2
  16000. +#define AR7240_PORT_VLAN_MODE_SECURE 3
  16001. +
  16002. +
  16003. +#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100)
  16004. +
  16005. +#define AR7240_STATS_RXBROAD 0x00
  16006. +#define AR7240_STATS_RXPAUSE 0x04
  16007. +#define AR7240_STATS_RXMULTI 0x08
  16008. +#define AR7240_STATS_RXFCSERR 0x0c
  16009. +#define AR7240_STATS_RXALIGNERR 0x10
  16010. +#define AR7240_STATS_RXRUNT 0x14
  16011. +#define AR7240_STATS_RXFRAGMENT 0x18
  16012. +#define AR7240_STATS_RX64BYTE 0x1c
  16013. +#define AR7240_STATS_RX128BYTE 0x20
  16014. +#define AR7240_STATS_RX256BYTE 0x24
  16015. +#define AR7240_STATS_RX512BYTE 0x28
  16016. +#define AR7240_STATS_RX1024BYTE 0x2c
  16017. +#define AR7240_STATS_RX1518BYTE 0x30
  16018. +#define AR7240_STATS_RXMAXBYTE 0x34
  16019. +#define AR7240_STATS_RXTOOLONG 0x38
  16020. +#define AR7240_STATS_RXGOODBYTE 0x3c
  16021. +#define AR7240_STATS_RXBADBYTE 0x44
  16022. +#define AR7240_STATS_RXOVERFLOW 0x4c
  16023. +#define AR7240_STATS_FILTERED 0x50
  16024. +#define AR7240_STATS_TXBROAD 0x54
  16025. +#define AR7240_STATS_TXPAUSE 0x58
  16026. +#define AR7240_STATS_TXMULTI 0x5c
  16027. +#define AR7240_STATS_TXUNDERRUN 0x60
  16028. +#define AR7240_STATS_TX64BYTE 0x64
  16029. +#define AR7240_STATS_TX128BYTE 0x68
  16030. +#define AR7240_STATS_TX256BYTE 0x6c
  16031. +#define AR7240_STATS_TX512BYTE 0x70
  16032. +#define AR7240_STATS_TX1024BYTE 0x74
  16033. +#define AR7240_STATS_TX1518BYTE 0x78
  16034. +#define AR7240_STATS_TXMAXBYTE 0x7c
  16035. +#define AR7240_STATS_TXOVERSIZE 0x80
  16036. +#define AR7240_STATS_TXBYTE 0x84
  16037. +#define AR7240_STATS_TXCOLLISION 0x8c
  16038. +#define AR7240_STATS_TXABORTCOL 0x90
  16039. +#define AR7240_STATS_TXMULTICOL 0x94
  16040. +#define AR7240_STATS_TXSINGLECOL 0x98
  16041. +#define AR7240_STATS_TXEXCDEFER 0x9c
  16042. +#define AR7240_STATS_TXDEFER 0xa0
  16043. +#define AR7240_STATS_TXLATECOL 0xa4
  16044. +
  16045. +#define AR7240_PORT_CPU 0
  16046. +#define AR7240_NUM_PORTS 6
  16047. +#define AR7240_NUM_PHYS 5
  16048. +
  16049. +#define AR7240_PHY_ID1 0x004d
  16050. +#define AR7240_PHY_ID2 0xd041
  16051. +
  16052. +#define AR7240_PORT_MASK(_port) BIT((_port))
  16053. +#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS)
  16054. +#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port)))
  16055. +
  16056. +#define AR7240_MAX_VLANS 16
  16057. +
  16058. +#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev)
  16059. +
  16060. +struct ar7240sw {
  16061. + struct mii_bus *mii_bus;
  16062. + struct switch_dev swdev;
  16063. + bool vlan;
  16064. + u16 vlan_id[AR7240_MAX_VLANS];
  16065. + u8 vlan_table[AR7240_MAX_VLANS];
  16066. + u8 vlan_tagged;
  16067. + u16 pvid[AR7240_NUM_PORTS];
  16068. +};
  16069. +
  16070. +struct ar7240sw_hw_stat {
  16071. + char string[ETH_GSTRING_LEN];
  16072. + int sizeof_stat;
  16073. + int reg;
  16074. +};
  16075. +
  16076. +static DEFINE_MUTEX(reg_mutex);
  16077. +
  16078. +static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
  16079. +{
  16080. + as->mii_bus = mii;
  16081. +}
  16082. +
  16083. +static inline u16 mk_phy_addr(u32 reg)
  16084. +{
  16085. + return 0x17 & ((reg >> 4) | 0x10);
  16086. +}
  16087. +
  16088. +static inline u16 mk_phy_reg(u32 reg)
  16089. +{
  16090. + return (reg << 1) & 0x1e;
  16091. +}
  16092. +
  16093. +static inline u16 mk_high_addr(u32 reg)
  16094. +{
  16095. + return (reg >> 7) & 0x1ff;
  16096. +}
  16097. +
  16098. +static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg)
  16099. +{
  16100. + unsigned long flags;
  16101. + u16 phy_addr;
  16102. + u16 phy_reg;
  16103. + u32 hi, lo;
  16104. +
  16105. + reg = (reg & 0xfffffffc) >> 2;
  16106. + phy_addr = mk_phy_addr(reg);
  16107. + phy_reg = mk_phy_reg(reg);
  16108. +
  16109. + local_irq_save(flags);
  16110. + ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg));
  16111. + lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg);
  16112. + hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1);
  16113. + local_irq_restore(flags);
  16114. +
  16115. + return (hi << 16) | lo;
  16116. +}
  16117. +
  16118. +static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val)
  16119. +{
  16120. + unsigned long flags;
  16121. + u16 phy_addr;
  16122. + u16 phy_reg;
  16123. +
  16124. + reg = (reg & 0xfffffffc) >> 2;
  16125. + phy_addr = mk_phy_addr(reg);
  16126. + phy_reg = mk_phy_reg(reg);
  16127. +
  16128. + local_irq_save(flags);
  16129. + ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg));
  16130. + ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16));
  16131. + ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff));
  16132. + local_irq_restore(flags);
  16133. +}
  16134. +
  16135. +static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr)
  16136. +{
  16137. + u32 ret;
  16138. +
  16139. + mutex_lock(&reg_mutex);
  16140. + ret = __ar7240sw_reg_read(mii, reg_addr);
  16141. + mutex_unlock(&reg_mutex);
  16142. +
  16143. + return ret;
  16144. +}
  16145. +
  16146. +static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val)
  16147. +{
  16148. + mutex_lock(&reg_mutex);
  16149. + __ar7240sw_reg_write(mii, reg_addr, reg_val);
  16150. + mutex_unlock(&reg_mutex);
  16151. +}
  16152. +
  16153. +static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val)
  16154. +{
  16155. + u32 t;
  16156. +
  16157. + mutex_lock(&reg_mutex);
  16158. + t = __ar7240sw_reg_read(mii, reg);
  16159. + t &= ~mask;
  16160. + t |= val;
  16161. + __ar7240sw_reg_write(mii, reg, t);
  16162. + mutex_unlock(&reg_mutex);
  16163. +
  16164. + return t;
  16165. +}
  16166. +
  16167. +static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val)
  16168. +{
  16169. + u32 t;
  16170. +
  16171. + mutex_lock(&reg_mutex);
  16172. + t = __ar7240sw_reg_read(mii, reg);
  16173. + t |= val;
  16174. + __ar7240sw_reg_write(mii, reg, t);
  16175. + mutex_unlock(&reg_mutex);
  16176. +}
  16177. +
  16178. +static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val,
  16179. + unsigned timeout)
  16180. +{
  16181. + int i;
  16182. +
  16183. + for (i = 0; i < timeout; i++) {
  16184. + u32 t;
  16185. +
  16186. + t = __ar7240sw_reg_read(mii, reg);
  16187. + if ((t & mask) == val)
  16188. + return 0;
  16189. +
  16190. + msleep(1);
  16191. + }
  16192. +
  16193. + return -ETIMEDOUT;
  16194. +}
  16195. +
  16196. +static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val,
  16197. + unsigned timeout)
  16198. +{
  16199. + int ret;
  16200. +
  16201. + mutex_lock(&reg_mutex);
  16202. + ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout);
  16203. + mutex_unlock(&reg_mutex);
  16204. + return ret;
  16205. +}
  16206. +
  16207. +u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr,
  16208. + unsigned reg_addr)
  16209. +{
  16210. + u32 t, val = 0xffff;
  16211. + int err;
  16212. +
  16213. + if (phy_addr >= AR7240_NUM_PHYS)
  16214. + return 0xffff;
  16215. +
  16216. + mutex_lock(&reg_mutex);
  16217. + t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  16218. + (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  16219. + AR7240_MDIO_CTRL_MASTER_EN |
  16220. + AR7240_MDIO_CTRL_BUSY |
  16221. + AR7240_MDIO_CTRL_CMD_READ;
  16222. +
  16223. + __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t);
  16224. + err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL,
  16225. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  16226. + if (!err)
  16227. + val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL);
  16228. + mutex_unlock(&reg_mutex);
  16229. +
  16230. + return val & AR7240_MDIO_CTRL_DATA_M;
  16231. +}
  16232. +
  16233. +int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr,
  16234. + unsigned reg_addr, u16 reg_val)
  16235. +{
  16236. + u32 t;
  16237. + int ret;
  16238. +
  16239. + if (phy_addr >= AR7240_NUM_PHYS)
  16240. + return -EINVAL;
  16241. +
  16242. + mutex_lock(&reg_mutex);
  16243. + t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  16244. + (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  16245. + AR7240_MDIO_CTRL_MASTER_EN |
  16246. + AR7240_MDIO_CTRL_BUSY |
  16247. + AR7240_MDIO_CTRL_CMD_WRITE |
  16248. + reg_val;
  16249. +
  16250. + __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t);
  16251. + ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL,
  16252. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  16253. + mutex_unlock(&reg_mutex);
  16254. +
  16255. + return ret;
  16256. +}
  16257. +
  16258. +static int ar7240sw_capture_stats(struct ar7240sw *as)
  16259. +{
  16260. + struct mii_bus *mii = as->mii_bus;
  16261. + int ret;
  16262. +
  16263. + /* Capture the hardware statistics for all ports */
  16264. + ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0,
  16265. + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
  16266. +
  16267. + /* Wait for the capturing to complete. */
  16268. + ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0,
  16269. + AR7240_MIB_BUSY, 0, 10);
  16270. + return ret;
  16271. +}
  16272. +
  16273. +static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
  16274. +{
  16275. + ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port),
  16276. + AR7240_PORT_CTRL_STATE_DISABLED);
  16277. +}
  16278. +
  16279. +static void ar7240sw_setup(struct ar7240sw *as)
  16280. +{
  16281. + struct mii_bus *mii = as->mii_bus;
  16282. +
  16283. + /* Enable CPU port, and disable mirror port */
  16284. + ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT,
  16285. + AR7240_CPU_PORT_EN |
  16286. + (15 << AR7240_MIRROR_PORT_S));
  16287. +
  16288. + /* Setup TAG priority mapping */
  16289. + ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50);
  16290. +
  16291. + /* Enable ARP frame acknowledge, aging, MAC replacing */
  16292. + ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL,
  16293. + 0x2b /* 5 min age time */ |
  16294. + AR7240_AT_CTRL_AGE_EN |
  16295. + AR7240_AT_CTRL_ARP_EN |
  16296. + AR7240_AT_CTRL_LEARN_CHANGE);
  16297. +
  16298. + /* Enable Broadcast frames transmitted to the CPU */
  16299. + ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK,
  16300. + AR7240_FLOOD_MASK_BROAD_TO_CPU);
  16301. +
  16302. + /* setup MTU */
  16303. + ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
  16304. + 1536);
  16305. +
  16306. + /* setup Service TAG */
  16307. + ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0);
  16308. +}
  16309. +
  16310. +static int ar7240sw_reset(struct ar7240sw *as)
  16311. +{
  16312. + struct mii_bus *mii = as->mii_bus;
  16313. + int ret;
  16314. + int i;
  16315. +
  16316. + /* Set all ports to disabled state. */
  16317. + for (i = 0; i < AR7240_NUM_PORTS; i++)
  16318. + ar7240sw_disable_port(as, i);
  16319. +
  16320. + /* Wait for transmit queues to drain. */
  16321. + msleep(2);
  16322. +
  16323. + /* Reset the switch. */
  16324. + ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL,
  16325. + AR7240_MASK_CTRL_SOFT_RESET);
  16326. +
  16327. + ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL,
  16328. + AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
  16329. +
  16330. + ar7240sw_setup(as);
  16331. + return ret;
  16332. +}
  16333. +
  16334. +static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask)
  16335. +{
  16336. + struct mii_bus *mii = as->mii_bus;
  16337. + u32 ctrl;
  16338. + u32 dest_ports;
  16339. + u32 vlan;
  16340. +
  16341. + ctrl = AR7240_PORT_CTRL_STATE_FORWARD | AR7240_PORT_CTRL_LEARN |
  16342. + AR7240_PORT_CTRL_SINGLE_VLAN;
  16343. +
  16344. + if (port == AR7240_PORT_CPU) {
  16345. + ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port),
  16346. + AR7240_PORT_STATUS_SPEED_1000 |
  16347. + AR7240_PORT_STATUS_TXFLOW |
  16348. + AR7240_PORT_STATUS_RXFLOW |
  16349. + AR7240_PORT_STATUS_TXMAC |
  16350. + AR7240_PORT_STATUS_RXMAC |
  16351. + AR7240_PORT_STATUS_DUPLEX);
  16352. + } else {
  16353. + ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port),
  16354. + AR7240_PORT_STATUS_LINK_AUTO);
  16355. + }
  16356. +
  16357. + /* Set the default VID for this port */
  16358. + if (as->vlan) {
  16359. + vlan = as->vlan_id[as->pvid[port]];
  16360. + vlan |= AR7240_PORT_VLAN_MODE_SECURE <<
  16361. + AR7240_PORT_VLAN_MODE_S;
  16362. + } else {
  16363. + vlan = port;
  16364. + vlan |= AR7240_PORT_VLAN_MODE_PORT_ONLY <<
  16365. + AR7240_PORT_VLAN_MODE_S;
  16366. + }
  16367. +
  16368. + if (as->vlan && (as->vlan_tagged & BIT(port))) {
  16369. + ctrl |= AR7240_PORT_CTRL_VLAN_MODE_ADD <<
  16370. + AR7240_PORT_CTRL_VLAN_MODE_S;
  16371. + } else {
  16372. + ctrl |= AR7240_PORT_CTRL_VLAN_MODE_STRIP <<
  16373. + AR7240_PORT_CTRL_VLAN_MODE_S;
  16374. + }
  16375. +
  16376. + if (!portmask) {
  16377. + if (port == AR7240_PORT_CPU)
  16378. + portmask = AR7240_PORT_MASK_BUT(AR7240_PORT_CPU);
  16379. + else
  16380. + portmask = AR7240_PORT_MASK(AR7240_PORT_CPU);
  16381. + }
  16382. +
  16383. + /* allow the port to talk to all other ports, but exclude its
  16384. + * own ID to prevent frames from being reflected back to the
  16385. + * port that they came from */
  16386. + dest_ports = AR7240_PORT_MASK_BUT(port);
  16387. +
  16388. + /* set default VID and and destination ports for this VLAN */
  16389. + vlan |= (portmask << AR7240_PORT_VLAN_DEST_PORTS_S);
  16390. +
  16391. + ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl);
  16392. + ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan);
  16393. +}
  16394. +
  16395. +static int ar7240_set_addr(struct ar7240sw *as, u8 *addr)
  16396. +{
  16397. + struct mii_bus *mii = as->mii_bus;
  16398. + u32 t;
  16399. +
  16400. + t = (addr[4] << 8) | addr[5];
  16401. + ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t);
  16402. +
  16403. + t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
  16404. + ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t);
  16405. +
  16406. + return 0;
  16407. +}
  16408. +
  16409. +static int
  16410. +ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
  16411. + struct switch_val *val)
  16412. +{
  16413. + struct ar7240sw *as = sw_to_ar7240(dev);
  16414. + as->vlan_id[val->port_vlan] = val->value.i;
  16415. + return 0;
  16416. +}
  16417. +
  16418. +static int
  16419. +ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
  16420. + struct switch_val *val)
  16421. +{
  16422. + struct ar7240sw *as = sw_to_ar7240(dev);
  16423. + val->value.i = as->vlan_id[val->port_vlan];
  16424. + return 0;
  16425. +}
  16426. +
  16427. +static int
  16428. +ar7240_set_pvid(struct switch_dev *dev, int port, int vlan)
  16429. +{
  16430. + struct ar7240sw *as = sw_to_ar7240(dev);
  16431. +
  16432. + /* make sure no invalid PVIDs get set */
  16433. +
  16434. + if (vlan >= dev->vlans)
  16435. + return -EINVAL;
  16436. +
  16437. + as->pvid[port] = vlan;
  16438. + return 0;
  16439. +}
  16440. +
  16441. +static int
  16442. +ar7240_get_pvid(struct switch_dev *dev, int port, int *vlan)
  16443. +{
  16444. + struct ar7240sw *as = sw_to_ar7240(dev);
  16445. + *vlan = as->pvid[port];
  16446. + return 0;
  16447. +}
  16448. +
  16449. +static int
  16450. +ar7240_get_ports(struct switch_dev *dev, struct switch_val *val)
  16451. +{
  16452. + struct ar7240sw *as = sw_to_ar7240(dev);
  16453. + u8 ports = as->vlan_table[val->port_vlan];
  16454. + int i;
  16455. +
  16456. + val->len = 0;
  16457. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  16458. + struct switch_port *p;
  16459. +
  16460. + if (!(ports & (1 << i)))
  16461. + continue;
  16462. +
  16463. + p = &val->value.ports[val->len++];
  16464. + p->id = i;
  16465. + if (as->vlan_tagged & (1 << i))
  16466. + p->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
  16467. + else
  16468. + p->flags = 0;
  16469. + }
  16470. + return 0;
  16471. +}
  16472. +
  16473. +static int
  16474. +ar7240_set_ports(struct switch_dev *dev, struct switch_val *val)
  16475. +{
  16476. + struct ar7240sw *as = sw_to_ar7240(dev);
  16477. + u8 *vt = &as->vlan_table[val->port_vlan];
  16478. + int i, j;
  16479. +
  16480. + *vt = 0;
  16481. + for (i = 0; i < val->len; i++) {
  16482. + struct switch_port *p = &val->value.ports[i];
  16483. +
  16484. + if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED))
  16485. + as->vlan_tagged |= (1 << p->id);
  16486. + else {
  16487. + as->vlan_tagged &= ~(1 << p->id);
  16488. + as->pvid[p->id] = val->port_vlan;
  16489. +
  16490. + /* make sure that an untagged port does not
  16491. + * appear in other vlans */
  16492. + for (j = 0; j < AR7240_MAX_VLANS; j++) {
  16493. + if (j == val->port_vlan)
  16494. + continue;
  16495. + as->vlan_table[j] &= ~(1 << p->id);
  16496. + }
  16497. + }
  16498. +
  16499. + *vt |= 1 << p->id;
  16500. + }
  16501. + return 0;
  16502. +}
  16503. +
  16504. +static int
  16505. +ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
  16506. + struct switch_val *val)
  16507. +{
  16508. + struct ar7240sw *as = sw_to_ar7240(dev);
  16509. + as->vlan = !!val->value.i;
  16510. + return 0;
  16511. +}
  16512. +
  16513. +static int
  16514. +ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
  16515. + struct switch_val *val)
  16516. +{
  16517. + struct ar7240sw *as = sw_to_ar7240(dev);
  16518. + val->value.i = as->vlan;
  16519. + return 0;
  16520. +}
  16521. +
  16522. +
  16523. +static void
  16524. +ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val)
  16525. +{
  16526. + struct mii_bus *mii = as->mii_bus;
  16527. +
  16528. + if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5))
  16529. + return;
  16530. +
  16531. + if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) {
  16532. + val &= AR7240_VTUDATA_MEMBER;
  16533. + val |= AR7240_VTUDATA_VALID;
  16534. + ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val);
  16535. + }
  16536. + op |= AR7240_VTU_ACTIVE;
  16537. + ar7240sw_reg_write(mii, AR7240_REG_VTU, op);
  16538. +}
  16539. +
  16540. +static int
  16541. +ar7240_hw_apply(struct switch_dev *dev)
  16542. +{
  16543. + struct ar7240sw *as = sw_to_ar7240(dev);
  16544. + u8 portmask[AR7240_NUM_PORTS];
  16545. + int i, j;
  16546. +
  16547. + /* flush all vlan translation unit entries */
  16548. + ar7240_vtu_op(as, AR7240_VTU_OP_FLUSH, 0);
  16549. +
  16550. + memset(portmask, 0, sizeof(portmask));
  16551. + if (as->vlan) {
  16552. + /* calculate the port destination masks and load vlans
  16553. + * into the vlan translation unit */
  16554. + for (j = 0; j < AR7240_MAX_VLANS; j++) {
  16555. + u8 vp = as->vlan_table[j];
  16556. +
  16557. + if (!vp)
  16558. + continue;
  16559. +
  16560. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  16561. + u8 mask = (1 << i);
  16562. + if (vp & mask)
  16563. + portmask[i] |= vp & ~mask;
  16564. + }
  16565. +
  16566. + ar7240_vtu_op(as,
  16567. + AR7240_VTU_OP_LOAD |
  16568. + (as->vlan_id[j] << AR7240_VTU_VID_S),
  16569. + as->vlan_table[j]);
  16570. + }
  16571. + } else {
  16572. + /* vlan disabled:
  16573. + * isolate all ports, but connect them to the cpu port */
  16574. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  16575. + if (i == AR7240_PORT_CPU)
  16576. + continue;
  16577. +
  16578. + portmask[i] = 1 << AR7240_PORT_CPU;
  16579. + portmask[AR7240_PORT_CPU] |= (1 << i);
  16580. + }
  16581. + }
  16582. +
  16583. + /* update the port destination mask registers and tag settings */
  16584. + for (i = 0; i < AR7240_NUM_PORTS; i++)
  16585. + ar7240sw_setup_port(as, i, portmask[i]);
  16586. +
  16587. + return 0;
  16588. +}
  16589. +
  16590. +static int
  16591. +ar7240_reset_switch(struct switch_dev *dev)
  16592. +{
  16593. + struct ar7240sw *as = sw_to_ar7240(dev);
  16594. + ar7240sw_reset(as);
  16595. + return 0;
  16596. +}
  16597. +
  16598. +static struct switch_attr ar7240_globals[] = {
  16599. + {
  16600. + .type = SWITCH_TYPE_INT,
  16601. + .name = "enable_vlan",
  16602. + .description = "Enable VLAN mode",
  16603. + .set = ar7240_set_vlan,
  16604. + .get = ar7240_get_vlan,
  16605. + .max = 1
  16606. + },
  16607. +};
  16608. +
  16609. +static struct switch_attr ar7240_port[] = {
  16610. +};
  16611. +
  16612. +static struct switch_attr ar7240_vlan[] = {
  16613. + {
  16614. + .type = SWITCH_TYPE_INT,
  16615. + .name = "vid",
  16616. + .description = "VLAN ID",
  16617. + .set = ar7240_set_vid,
  16618. + .get = ar7240_get_vid,
  16619. + .max = 4094,
  16620. + },
  16621. +};
  16622. +
  16623. +static const struct switch_dev_ops ar7240_ops = {
  16624. + .attr_global = {
  16625. + .attr = ar7240_globals,
  16626. + .n_attr = ARRAY_SIZE(ar7240_globals),
  16627. + },
  16628. + .attr_port = {
  16629. + .attr = ar7240_port,
  16630. + .n_attr = ARRAY_SIZE(ar7240_port),
  16631. + },
  16632. + .attr_vlan = {
  16633. + .attr = ar7240_vlan,
  16634. + .n_attr = ARRAY_SIZE(ar7240_vlan),
  16635. + },
  16636. + .get_port_pvid = ar7240_get_pvid,
  16637. + .set_port_pvid = ar7240_set_pvid,
  16638. + .get_vlan_ports = ar7240_get_ports,
  16639. + .set_vlan_ports = ar7240_set_ports,
  16640. + .apply_config = ar7240_hw_apply,
  16641. + .reset_switch = ar7240_reset_switch,
  16642. +};
  16643. +
  16644. +static struct ar7240sw *ar7240_probe(struct ag71xx *ag)
  16645. +{
  16646. + struct mii_bus *mii = ag->mii_bus;
  16647. + struct ar7240sw *as;
  16648. + struct switch_dev *swdev;
  16649. + u32 ctrl;
  16650. + u16 phy_id1;
  16651. + u16 phy_id2;
  16652. + u8 ver;
  16653. + int i;
  16654. +
  16655. + as = kzalloc(sizeof(*as), GFP_KERNEL);
  16656. + if (!as)
  16657. + return NULL;
  16658. +
  16659. + ar7240sw_init(as, mii);
  16660. +
  16661. + ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL);
  16662. +
  16663. + ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
  16664. + if (ver != 1) {
  16665. + pr_err("%s: unsupported chip, ctrl=%08x\n",
  16666. + ag->dev->name, ctrl);
  16667. + return NULL;
  16668. + }
  16669. +
  16670. + phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1);
  16671. + phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2);
  16672. + if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
  16673. + pr_err("%s: unknown phy id '%04x:%04x'\n",
  16674. + ag->dev->name, phy_id1, phy_id2);
  16675. + return NULL;
  16676. + }
  16677. +
  16678. + swdev = &as->swdev;
  16679. + swdev->name = "AR7240 built-in switch";
  16680. + swdev->ports = AR7240_NUM_PORTS;
  16681. + swdev->cpu_port = AR7240_PORT_CPU;
  16682. + swdev->vlans = AR7240_MAX_VLANS;
  16683. + swdev->ops = &ar7240_ops;
  16684. +
  16685. + if (register_switch(&as->swdev, ag->dev) < 0) {
  16686. + kfree(as);
  16687. + return NULL;
  16688. + }
  16689. +
  16690. + pr_info("%s: Found an AR7240 built-in switch\n", ag->dev->name);
  16691. +
  16692. + /* initialize defaults */
  16693. + for (i = 0; i < AR7240_MAX_VLANS; i++)
  16694. + as->vlan_id[i] = i;
  16695. +
  16696. + as->vlan_table[0] = AR7240_PORT_MASK_ALL;
  16697. +
  16698. + return as;
  16699. +}
  16700. +
  16701. +static void link_function(struct work_struct *work) {
  16702. + struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work);
  16703. + unsigned long flags;
  16704. + int i;
  16705. + int status = 0;
  16706. +
  16707. + for (i = 0; i < 4; i++) {
  16708. + int link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR);
  16709. + if(link & BMSR_LSTATUS) {
  16710. + status = 1;
  16711. + break;
  16712. + }
  16713. + }
  16714. +
  16715. + spin_lock_irqsave(&ag->lock, flags);
  16716. + if(status != ag->link) {
  16717. + ag->link = status;
  16718. + ag71xx_link_adjust(ag);
  16719. + }
  16720. + spin_unlock_irqrestore(&ag->lock, flags);
  16721. +
  16722. + schedule_delayed_work(&ag->link_work, HZ / 2);
  16723. +}
  16724. +
  16725. +void ag71xx_ar7240_start(struct ag71xx *ag)
  16726. +{
  16727. + struct ar7240sw *as = ag->phy_priv;
  16728. +
  16729. + ar7240sw_reset(as);
  16730. +
  16731. + ag->speed = SPEED_1000;
  16732. + ag->duplex = 1;
  16733. +
  16734. + ar7240_set_addr(as, ag->dev->dev_addr);
  16735. + ar7240_hw_apply(&as->swdev);
  16736. +
  16737. + schedule_delayed_work(&ag->link_work, HZ / 10);
  16738. +}
  16739. +
  16740. +void ag71xx_ar7240_stop(struct ag71xx *ag)
  16741. +{
  16742. + cancel_delayed_work_sync(&ag->link_work);
  16743. +}
  16744. +
  16745. +int __devinit ag71xx_ar7240_init(struct ag71xx *ag)
  16746. +{
  16747. + struct ar7240sw *as;
  16748. +
  16749. + as = ar7240_probe(ag);
  16750. + if (!as)
  16751. + return -ENODEV;
  16752. +
  16753. + ag->phy_priv = as;
  16754. + ar7240sw_reset(as);
  16755. +
  16756. + INIT_DELAYED_WORK(&ag->link_work, link_function);
  16757. +
  16758. + return 0;
  16759. +}
  16760. +
  16761. +void ag71xx_ar7240_cleanup(struct ag71xx *ag)
  16762. +{
  16763. + struct ar7240sw *as = ag->phy_priv;
  16764. +
  16765. + if (!as)
  16766. + return;
  16767. +
  16768. + unregister_switch(&as->swdev);
  16769. + kfree(as);
  16770. + ag->phy_priv = NULL;
  16771. +}
  16772. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c
  16773. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100
  16774. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-08-24 18:17:24.000000000 +0200
  16775. @@ -0,0 +1,44 @@
  16776. +/*
  16777. + * Atheros AR71xx built-in ethernet mac driver
  16778. + * Special support for the Atheros ar8216 switch chip
  16779. + *
  16780. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  16781. + *
  16782. + * Based on Atheros' AG7100 driver
  16783. + *
  16784. + * This program is free software; you can redistribute it and/or modify it
  16785. + * under the terms of the GNU General Public License version 2 as published
  16786. + * by the Free Software Foundation.
  16787. + */
  16788. +
  16789. +#include "ag71xx.h"
  16790. +
  16791. +#define AR8216_PACKET_TYPE_MASK 0xf
  16792. +#define AR8216_PACKET_TYPE_NORMAL 0
  16793. +
  16794. +#define AR8216_HEADER_LEN 2
  16795. +
  16796. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
  16797. +{
  16798. + skb_push(skb, AR8216_HEADER_LEN);
  16799. + skb->data[0] = 0x10;
  16800. + skb->data[1] = 0x80;
  16801. +}
  16802. +
  16803. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  16804. + int pktlen)
  16805. +{
  16806. + u8 type;
  16807. +
  16808. + type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
  16809. + switch (type) {
  16810. + case AR8216_PACKET_TYPE_NORMAL:
  16811. + break;
  16812. +
  16813. + default:
  16814. + return -EINVAL;
  16815. + }
  16816. +
  16817. + skb_pull(skb, AR8216_HEADER_LEN);
  16818. + return 0;
  16819. +}
  16820. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c
  16821. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  16822. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-08-24 18:17:24.000000000 +0200
  16823. @@ -0,0 +1,280 @@
  16824. +/*
  16825. + * Atheros AR71xx built-in ethernet mac driver
  16826. + *
  16827. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  16828. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16829. + *
  16830. + * Based on Atheros' AG7100 driver
  16831. + *
  16832. + * This program is free software; you can redistribute it and/or modify it
  16833. + * under the terms of the GNU General Public License version 2 as published
  16834. + * by the Free Software Foundation.
  16835. + */
  16836. +
  16837. +#include <linux/debugfs.h>
  16838. +
  16839. +#include "ag71xx.h"
  16840. +
  16841. +static struct dentry *ag71xx_debugfs_root;
  16842. +
  16843. +static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file)
  16844. +{
  16845. + file->private_data = inode->i_private;
  16846. + return 0;
  16847. +}
  16848. +
  16849. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status)
  16850. +{
  16851. + if (status)
  16852. + ag->debug.int_stats.total++;
  16853. + if (status & AG71XX_INT_TX_PS)
  16854. + ag->debug.int_stats.tx_ps++;
  16855. + if (status & AG71XX_INT_TX_UR)
  16856. + ag->debug.int_stats.tx_ur++;
  16857. + if (status & AG71XX_INT_TX_BE)
  16858. + ag->debug.int_stats.tx_be++;
  16859. + if (status & AG71XX_INT_RX_PR)
  16860. + ag->debug.int_stats.rx_pr++;
  16861. + if (status & AG71XX_INT_RX_OF)
  16862. + ag->debug.int_stats.rx_of++;
  16863. + if (status & AG71XX_INT_RX_BE)
  16864. + ag->debug.int_stats.rx_be++;
  16865. +}
  16866. +
  16867. +static ssize_t read_file_int_stats(struct file *file, char __user *user_buf,
  16868. + size_t count, loff_t *ppos)
  16869. +{
  16870. +#define PR_INT_STAT(_label, _field) \
  16871. + len += snprintf(buf + len, sizeof(buf) - len, \
  16872. + "%20s: %10lu\n", _label, ag->debug.int_stats._field);
  16873. +
  16874. + struct ag71xx *ag = file->private_data;
  16875. + char buf[256];
  16876. + unsigned int len = 0;
  16877. +
  16878. + PR_INT_STAT("TX Packet Sent", tx_ps);
  16879. + PR_INT_STAT("TX Underrun", tx_ur);
  16880. + PR_INT_STAT("TX Bus Error", tx_be);
  16881. + PR_INT_STAT("RX Packet Received", rx_pr);
  16882. + PR_INT_STAT("RX Overflow", rx_of);
  16883. + PR_INT_STAT("RX Bus Error", rx_be);
  16884. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  16885. + PR_INT_STAT("Total", total);
  16886. +
  16887. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  16888. +#undef PR_INT_STAT
  16889. +}
  16890. +
  16891. +static const struct file_operations ag71xx_fops_int_stats = {
  16892. + .open = ag71xx_debugfs_generic_open,
  16893. + .read = read_file_int_stats,
  16894. + .owner = THIS_MODULE
  16895. +};
  16896. +
  16897. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
  16898. +{
  16899. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  16900. +
  16901. + if (rx) {
  16902. + stats->rx_count++;
  16903. + stats->rx_packets += rx;
  16904. + if (rx <= AG71XX_NAPI_WEIGHT)
  16905. + stats->rx[rx]++;
  16906. + if (rx > stats->rx_packets_max)
  16907. + stats->rx_packets_max = rx;
  16908. + }
  16909. +
  16910. + if (tx) {
  16911. + stats->tx_count++;
  16912. + stats->tx_packets += tx;
  16913. + if (tx <= AG71XX_NAPI_WEIGHT)
  16914. + stats->tx[tx]++;
  16915. + if (tx > stats->tx_packets_max)
  16916. + stats->tx_packets_max = tx;
  16917. + }
  16918. +}
  16919. +
  16920. +static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf,
  16921. + size_t count, loff_t *ppos)
  16922. +{
  16923. + struct ag71xx *ag = file->private_data;
  16924. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  16925. + char *buf;
  16926. + unsigned int buflen;
  16927. + unsigned int len = 0;
  16928. + unsigned long rx_avg = 0;
  16929. + unsigned long tx_avg = 0;
  16930. + int ret;
  16931. + int i;
  16932. +
  16933. + buflen = 2048;
  16934. + buf = kmalloc(buflen, GFP_KERNEL);
  16935. + if (!buf)
  16936. + return -ENOMEM;
  16937. +
  16938. + if (stats->rx_count)
  16939. + rx_avg = stats->rx_packets / stats->rx_count;
  16940. +
  16941. + if (stats->tx_count)
  16942. + tx_avg = stats->tx_packets / stats->tx_count;
  16943. +
  16944. + len += snprintf(buf + len, buflen - len, "%3s %10s %10s\n",
  16945. + "len", "rx", "tx");
  16946. +
  16947. + for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++)
  16948. + len += snprintf(buf + len, buflen - len,
  16949. + "%3d: %10lu %10lu\n",
  16950. + i, stats->rx[i], stats->tx[i]);
  16951. +
  16952. + len += snprintf(buf + len, buflen - len, "\n");
  16953. +
  16954. + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n",
  16955. + "sum", stats->rx_count, stats->tx_count);
  16956. + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n",
  16957. + "avg", rx_avg, tx_avg);
  16958. + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n",
  16959. + "max", stats->rx_packets_max, stats->tx_packets_max);
  16960. + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n",
  16961. + "pkt", stats->rx_packets, stats->tx_packets);
  16962. +
  16963. + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
  16964. + kfree(buf);
  16965. +
  16966. + return ret;
  16967. +}
  16968. +
  16969. +static const struct file_operations ag71xx_fops_napi_stats = {
  16970. + .open = ag71xx_debugfs_generic_open,
  16971. + .read = read_file_napi_stats,
  16972. + .owner = THIS_MODULE
  16973. +};
  16974. +
  16975. +#define DESC_PRINT_LEN 64
  16976. +
  16977. +static ssize_t read_file_ring(struct file *file, char __user *user_buf,
  16978. + size_t count, loff_t *ppos,
  16979. + struct ag71xx *ag,
  16980. + struct ag71xx_ring *ring,
  16981. + unsigned desc_reg)
  16982. +{
  16983. + char *buf;
  16984. + unsigned int buflen;
  16985. + unsigned int len = 0;
  16986. + unsigned long flags;
  16987. + ssize_t ret;
  16988. + int curr;
  16989. + int dirty;
  16990. + u32 desc_hw;
  16991. + int i;
  16992. +
  16993. + buflen = (ring->size * DESC_PRINT_LEN);
  16994. + buf = kmalloc(buflen, GFP_KERNEL);
  16995. + if (!buf)
  16996. + return -ENOMEM;
  16997. +
  16998. + len += snprintf(buf + len, buflen - len,
  16999. + "Idx ... %-8s %-8s %-8s %-8s . %-10s\n",
  17000. + "desc", "next", "data", "ctrl", "timestamp");
  17001. +
  17002. + spin_lock_irqsave(&ag->lock, flags);
  17003. +
  17004. + curr = (ring->curr % ring->size);
  17005. + dirty = (ring->dirty % ring->size);
  17006. + desc_hw = ag71xx_rr(ag, desc_reg);
  17007. + for (i = 0; i < ring->size; i++) {
  17008. + struct ag71xx_buf *ab = &ring->buf[i];
  17009. + u32 desc_dma = ((u32) ring->descs_dma) + i * ring->desc_size;
  17010. +
  17011. + len += snprintf(buf + len, buflen - len,
  17012. + "%3d %c%c%c %08x %08x %08x %08x %c %10lu\n",
  17013. + i,
  17014. + (i == curr) ? 'C' : ' ',
  17015. + (i == dirty) ? 'D' : ' ',
  17016. + (desc_hw == desc_dma) ? 'H' : ' ',
  17017. + desc_dma,
  17018. + ab->desc->next,
  17019. + ab->desc->data,
  17020. + ab->desc->ctrl,
  17021. + (ab->desc->ctrl & DESC_EMPTY) ? 'E' : '*',
  17022. + ab->timestamp);
  17023. + }
  17024. +
  17025. + spin_unlock_irqrestore(&ag->lock, flags);
  17026. +
  17027. + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
  17028. + kfree(buf);
  17029. +
  17030. + return ret;
  17031. +}
  17032. +
  17033. +static ssize_t read_file_tx_ring(struct file *file, char __user *user_buf,
  17034. + size_t count, loff_t *ppos)
  17035. +{
  17036. + struct ag71xx *ag = file->private_data;
  17037. +
  17038. + return read_file_ring(file, user_buf, count, ppos, ag, &ag->tx_ring,
  17039. + AG71XX_REG_TX_DESC);
  17040. +}
  17041. +
  17042. +static const struct file_operations ag71xx_fops_tx_ring = {
  17043. + .open = ag71xx_debugfs_generic_open,
  17044. + .read = read_file_tx_ring,
  17045. + .owner = THIS_MODULE
  17046. +};
  17047. +
  17048. +static ssize_t read_file_rx_ring(struct file *file, char __user *user_buf,
  17049. + size_t count, loff_t *ppos)
  17050. +{
  17051. + struct ag71xx *ag = file->private_data;
  17052. +
  17053. + return read_file_ring(file, user_buf, count, ppos, ag, &ag->rx_ring,
  17054. + AG71XX_REG_RX_DESC);
  17055. +}
  17056. +
  17057. +static const struct file_operations ag71xx_fops_rx_ring = {
  17058. + .open = ag71xx_debugfs_generic_open,
  17059. + .read = read_file_rx_ring,
  17060. + .owner = THIS_MODULE
  17061. +};
  17062. +
  17063. +void ag71xx_debugfs_exit(struct ag71xx *ag)
  17064. +{
  17065. + debugfs_remove_recursive(ag->debug.debugfs_dir);
  17066. +}
  17067. +
  17068. +int ag71xx_debugfs_init(struct ag71xx *ag)
  17069. +{
  17070. + ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name,
  17071. + ag71xx_debugfs_root);
  17072. + if (!ag->debug.debugfs_dir)
  17073. + return -ENOMEM;
  17074. +
  17075. + debugfs_create_file("int_stats", S_IRUGO, ag->debug.debugfs_dir,
  17076. + ag, &ag71xx_fops_int_stats);
  17077. + debugfs_create_file("napi_stats", S_IRUGO, ag->debug.debugfs_dir,
  17078. + ag, &ag71xx_fops_napi_stats);
  17079. + debugfs_create_file("tx_ring", S_IRUGO, ag->debug.debugfs_dir,
  17080. + ag, &ag71xx_fops_tx_ring);
  17081. + debugfs_create_file("rx_ring", S_IRUGO, ag->debug.debugfs_dir,
  17082. + ag, &ag71xx_fops_rx_ring);
  17083. +
  17084. + return 0;
  17085. +}
  17086. +
  17087. +int ag71xx_debugfs_root_init(void)
  17088. +{
  17089. + if (ag71xx_debugfs_root)
  17090. + return -EBUSY;
  17091. +
  17092. + ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
  17093. + if (!ag71xx_debugfs_root)
  17094. + return -ENOENT;
  17095. +
  17096. + return 0;
  17097. +}
  17098. +
  17099. +void ag71xx_debugfs_root_exit(void)
  17100. +{
  17101. + debugfs_remove(ag71xx_debugfs_root);
  17102. + ag71xx_debugfs_root = NULL;
  17103. +}
  17104. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c
  17105. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
  17106. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-08-24 18:17:24.000000000 +0200
  17107. @@ -0,0 +1,124 @@
  17108. +/*
  17109. + * Atheros AR71xx built-in ethernet mac driver
  17110. + *
  17111. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  17112. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  17113. + *
  17114. + * Based on Atheros' AG7100 driver
  17115. + *
  17116. + * This program is free software; you can redistribute it and/or modify it
  17117. + * under the terms of the GNU General Public License version 2 as published
  17118. + * by the Free Software Foundation.
  17119. + */
  17120. +
  17121. +#include "ag71xx.h"
  17122. +
  17123. +static int ag71xx_ethtool_get_settings(struct net_device *dev,
  17124. + struct ethtool_cmd *cmd)
  17125. +{
  17126. + struct ag71xx *ag = netdev_priv(dev);
  17127. + struct phy_device *phydev = ag->phy_dev;
  17128. +
  17129. + if (!phydev)
  17130. + return -ENODEV;
  17131. +
  17132. + return phy_ethtool_gset(phydev, cmd);
  17133. +}
  17134. +
  17135. +static int ag71xx_ethtool_set_settings(struct net_device *dev,
  17136. + struct ethtool_cmd *cmd)
  17137. +{
  17138. + struct ag71xx *ag = netdev_priv(dev);
  17139. + struct phy_device *phydev = ag->phy_dev;
  17140. +
  17141. + if (!phydev)
  17142. + return -ENODEV;
  17143. +
  17144. + return phy_ethtool_sset(phydev, cmd);
  17145. +}
  17146. +
  17147. +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev,
  17148. + struct ethtool_drvinfo *info)
  17149. +{
  17150. + struct ag71xx *ag = netdev_priv(dev);
  17151. +
  17152. + strcpy(info->driver, ag->pdev->dev.driver->name);
  17153. + strcpy(info->version, AG71XX_DRV_VERSION);
  17154. + strcpy(info->bus_info, dev_name(&ag->pdev->dev));
  17155. +}
  17156. +
  17157. +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev)
  17158. +{
  17159. + struct ag71xx *ag = netdev_priv(dev);
  17160. +
  17161. + return ag->msg_enable;
  17162. +}
  17163. +
  17164. +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level)
  17165. +{
  17166. + struct ag71xx *ag = netdev_priv(dev);
  17167. +
  17168. + ag->msg_enable = msg_level;
  17169. +}
  17170. +
  17171. +static void ag71xx_ethtool_get_ringparam(struct net_device *dev,
  17172. + struct ethtool_ringparam *er)
  17173. +{
  17174. + struct ag71xx *ag = netdev_priv(dev);
  17175. +
  17176. + er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX;
  17177. + er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX;
  17178. + er->rx_mini_max_pending = 0;
  17179. + er->rx_jumbo_max_pending = 0;
  17180. +
  17181. + er->tx_pending = ag->tx_ring.size;
  17182. + er->rx_pending = ag->rx_ring.size;
  17183. + er->rx_mini_pending = 0;
  17184. + er->rx_jumbo_pending = 0;
  17185. +}
  17186. +
  17187. +static int ag71xx_ethtool_set_ringparam(struct net_device *dev,
  17188. + struct ethtool_ringparam *er)
  17189. +{
  17190. + struct ag71xx *ag = netdev_priv(dev);
  17191. + unsigned tx_size;
  17192. + unsigned rx_size;
  17193. + int err;
  17194. +
  17195. + if (er->rx_mini_pending != 0||
  17196. + er->rx_jumbo_pending != 0 ||
  17197. + er->rx_pending == 0 ||
  17198. + er->tx_pending == 0)
  17199. + return -EINVAL;
  17200. +
  17201. + tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ?
  17202. + er->tx_pending : AG71XX_TX_RING_SIZE_MAX;
  17203. +
  17204. + rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ?
  17205. + er->rx_pending : AG71XX_RX_RING_SIZE_MAX;
  17206. +
  17207. + if (netif_running(dev)) {
  17208. + err = dev->netdev_ops->ndo_stop(dev);
  17209. + if (err)
  17210. + return err;
  17211. + }
  17212. +
  17213. + ag->tx_ring.size = tx_size;
  17214. + ag->rx_ring.size = rx_size;
  17215. +
  17216. + if (netif_running(dev))
  17217. + err = dev->netdev_ops->ndo_open(dev);
  17218. +
  17219. + return err;
  17220. +}
  17221. +
  17222. +struct ethtool_ops ag71xx_ethtool_ops = {
  17223. + .set_settings = ag71xx_ethtool_set_settings,
  17224. + .get_settings = ag71xx_ethtool_get_settings,
  17225. + .get_drvinfo = ag71xx_ethtool_get_drvinfo,
  17226. + .get_msglevel = ag71xx_ethtool_get_msglevel,
  17227. + .set_msglevel = ag71xx_ethtool_set_msglevel,
  17228. + .get_ringparam = ag71xx_ethtool_get_ringparam,
  17229. + .set_ringparam = ag71xx_ethtool_set_ringparam,
  17230. + .get_link = ethtool_op_get_link,
  17231. +};
  17232. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c
  17233. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100
  17234. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-08-24 18:17:24.000000000 +0200
  17235. @@ -0,0 +1,1291 @@
  17236. +/*
  17237. + * Atheros AR71xx built-in ethernet mac driver
  17238. + *
  17239. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  17240. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  17241. + *
  17242. + * Based on Atheros' AG7100 driver
  17243. + *
  17244. + * This program is free software; you can redistribute it and/or modify it
  17245. + * under the terms of the GNU General Public License version 2 as published
  17246. + * by the Free Software Foundation.
  17247. + */
  17248. +
  17249. +#include "ag71xx.h"
  17250. +
  17251. +#define AG71XX_DEFAULT_MSG_ENABLE \
  17252. + (NETIF_MSG_DRV \
  17253. + | NETIF_MSG_PROBE \
  17254. + | NETIF_MSG_LINK \
  17255. + | NETIF_MSG_TIMER \
  17256. + | NETIF_MSG_IFDOWN \
  17257. + | NETIF_MSG_IFUP \
  17258. + | NETIF_MSG_RX_ERR \
  17259. + | NETIF_MSG_TX_ERR)
  17260. +
  17261. +static int ag71xx_msg_level = -1;
  17262. +
  17263. +module_param_named(msg_level, ag71xx_msg_level, int, 0);
  17264. +MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
  17265. +
  17266. +static void ag71xx_dump_dma_regs(struct ag71xx *ag)
  17267. +{
  17268. + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n",
  17269. + ag->dev->name,
  17270. + ag71xx_rr(ag, AG71XX_REG_TX_CTRL),
  17271. + ag71xx_rr(ag, AG71XX_REG_TX_DESC),
  17272. + ag71xx_rr(ag, AG71XX_REG_TX_STATUS));
  17273. +
  17274. + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n",
  17275. + ag->dev->name,
  17276. + ag71xx_rr(ag, AG71XX_REG_RX_CTRL),
  17277. + ag71xx_rr(ag, AG71XX_REG_RX_DESC),
  17278. + ag71xx_rr(ag, AG71XX_REG_RX_STATUS));
  17279. +}
  17280. +
  17281. +static void ag71xx_dump_regs(struct ag71xx *ag)
  17282. +{
  17283. + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n",
  17284. + ag->dev->name,
  17285. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1),
  17286. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  17287. + ag71xx_rr(ag, AG71XX_REG_MAC_IPG),
  17288. + ag71xx_rr(ag, AG71XX_REG_MAC_HDX),
  17289. + ag71xx_rr(ag, AG71XX_REG_MAC_MFL));
  17290. + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n",
  17291. + ag->dev->name,
  17292. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  17293. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1),
  17294. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2));
  17295. + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n",
  17296. + ag->dev->name,
  17297. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  17298. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  17299. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  17300. + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n",
  17301. + ag->dev->name,
  17302. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  17303. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  17304. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  17305. +}
  17306. +
  17307. +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
  17308. +{
  17309. + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n",
  17310. + ag->dev->name, label, intr,
  17311. + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "",
  17312. + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "",
  17313. + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "",
  17314. + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "",
  17315. + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "",
  17316. + (intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
  17317. +}
  17318. +
  17319. +static void ag71xx_ring_free(struct ag71xx_ring *ring)
  17320. +{
  17321. + kfree(ring->buf);
  17322. +
  17323. + if (ring->descs_cpu)
  17324. + dma_free_coherent(NULL, ring->size * ring->desc_size,
  17325. + ring->descs_cpu, ring->descs_dma);
  17326. +}
  17327. +
  17328. +static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
  17329. +{
  17330. + int err;
  17331. + int i;
  17332. +
  17333. + ring->desc_size = sizeof(struct ag71xx_desc);
  17334. + if (ring->desc_size % cache_line_size()) {
  17335. + DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
  17336. + ring, ring->desc_size,
  17337. + roundup(ring->desc_size, cache_line_size()));
  17338. + ring->desc_size = roundup(ring->desc_size, cache_line_size());
  17339. + }
  17340. +
  17341. + ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size,
  17342. + &ring->descs_dma, GFP_ATOMIC);
  17343. + if (!ring->descs_cpu) {
  17344. + err = -ENOMEM;
  17345. + goto err;
  17346. + }
  17347. +
  17348. +
  17349. + ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL);
  17350. + if (!ring->buf) {
  17351. + err = -ENOMEM;
  17352. + goto err;
  17353. + }
  17354. +
  17355. + for (i = 0; i < ring->size; i++) {
  17356. + int idx = i * ring->desc_size;
  17357. + ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx];
  17358. + DBG("ag71xx: ring %p, desc %d at %p\n",
  17359. + ring, i, ring->buf[i].desc);
  17360. + }
  17361. +
  17362. + return 0;
  17363. +
  17364. +err:
  17365. + return err;
  17366. +}
  17367. +
  17368. +static void ag71xx_ring_tx_clean(struct ag71xx *ag)
  17369. +{
  17370. + struct ag71xx_ring *ring = &ag->tx_ring;
  17371. + struct net_device *dev = ag->dev;
  17372. +
  17373. + while (ring->curr != ring->dirty) {
  17374. + u32 i = ring->dirty % ring->size;
  17375. +
  17376. + if (!ag71xx_desc_empty(ring->buf[i].desc)) {
  17377. + ring->buf[i].desc->ctrl = 0;
  17378. + dev->stats.tx_errors++;
  17379. + }
  17380. +
  17381. + if (ring->buf[i].skb)
  17382. + dev_kfree_skb_any(ring->buf[i].skb);
  17383. +
  17384. + ring->buf[i].skb = NULL;
  17385. +
  17386. + ring->dirty++;
  17387. + }
  17388. +
  17389. + /* flush descriptors */
  17390. + wmb();
  17391. +
  17392. +}
  17393. +
  17394. +static void ag71xx_ring_tx_init(struct ag71xx *ag)
  17395. +{
  17396. + struct ag71xx_ring *ring = &ag->tx_ring;
  17397. + int i;
  17398. +
  17399. + for (i = 0; i < ring->size; i++) {
  17400. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  17401. + ring->desc_size * ((i + 1) % ring->size));
  17402. +
  17403. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  17404. + ring->buf[i].skb = NULL;
  17405. + }
  17406. +
  17407. + /* flush descriptors */
  17408. + wmb();
  17409. +
  17410. + ring->curr = 0;
  17411. + ring->dirty = 0;
  17412. +}
  17413. +
  17414. +static void ag71xx_ring_rx_clean(struct ag71xx *ag)
  17415. +{
  17416. + struct ag71xx_ring *ring = &ag->rx_ring;
  17417. + int i;
  17418. +
  17419. + if (!ring->buf)
  17420. + return;
  17421. +
  17422. + for (i = 0; i < ring->size; i++)
  17423. + if (ring->buf[i].skb) {
  17424. + dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr,
  17425. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  17426. + kfree_skb(ring->buf[i].skb);
  17427. + }
  17428. +}
  17429. +
  17430. +static int ag71xx_rx_reserve(struct ag71xx *ag)
  17431. +{
  17432. + int reserve = 0;
  17433. +
  17434. + if (ag71xx_get_pdata(ag)->is_ar724x) {
  17435. + if (!ag71xx_has_ar8216(ag))
  17436. + reserve = 2;
  17437. +
  17438. + if (ag->phy_dev)
  17439. + reserve += 4 - (ag->phy_dev->pkt_align % 4);
  17440. +
  17441. + reserve %= 4;
  17442. + }
  17443. +
  17444. + return reserve + AG71XX_RX_PKT_RESERVE;
  17445. +}
  17446. +
  17447. +
  17448. +static int ag71xx_ring_rx_init(struct ag71xx *ag)
  17449. +{
  17450. + struct ag71xx_ring *ring = &ag->rx_ring;
  17451. + unsigned int reserve = ag71xx_rx_reserve(ag);
  17452. + unsigned int i;
  17453. + int ret;
  17454. +
  17455. + ret = 0;
  17456. + for (i = 0; i < ring->size; i++) {
  17457. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  17458. + ring->desc_size * ((i + 1) % ring->size));
  17459. +
  17460. + DBG("ag71xx: RX desc at %p, next is %08x\n",
  17461. + ring->buf[i].desc,
  17462. + ring->buf[i].desc->next);
  17463. + }
  17464. +
  17465. + for (i = 0; i < ring->size; i++) {
  17466. + struct sk_buff *skb;
  17467. + dma_addr_t dma_addr;
  17468. +
  17469. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  17470. + if (!skb) {
  17471. + ret = -ENOMEM;
  17472. + break;
  17473. + }
  17474. +
  17475. + skb->dev = ag->dev;
  17476. + skb_reserve(skb, reserve);
  17477. +
  17478. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  17479. + AG71XX_RX_PKT_SIZE,
  17480. + DMA_FROM_DEVICE);
  17481. + ring->buf[i].skb = skb;
  17482. + ring->buf[i].dma_addr = dma_addr;
  17483. + ring->buf[i].desc->data = (u32) dma_addr;
  17484. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  17485. + }
  17486. +
  17487. + /* flush descriptors */
  17488. + wmb();
  17489. +
  17490. + ring->curr = 0;
  17491. + ring->dirty = 0;
  17492. +
  17493. + return ret;
  17494. +}
  17495. +
  17496. +static int ag71xx_ring_rx_refill(struct ag71xx *ag)
  17497. +{
  17498. + struct ag71xx_ring *ring = &ag->rx_ring;
  17499. + unsigned int reserve = ag71xx_rx_reserve(ag);
  17500. + unsigned int count;
  17501. +
  17502. + count = 0;
  17503. + for (; ring->curr - ring->dirty > 0; ring->dirty++) {
  17504. + unsigned int i;
  17505. +
  17506. + i = ring->dirty % ring->size;
  17507. +
  17508. + if (ring->buf[i].skb == NULL) {
  17509. + dma_addr_t dma_addr;
  17510. + struct sk_buff *skb;
  17511. +
  17512. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  17513. + if (skb == NULL)
  17514. + break;
  17515. +
  17516. + skb_reserve(skb, reserve);
  17517. + skb->dev = ag->dev;
  17518. +
  17519. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  17520. + AG71XX_RX_PKT_SIZE,
  17521. + DMA_FROM_DEVICE);
  17522. +
  17523. + ring->buf[i].skb = skb;
  17524. + ring->buf[i].dma_addr = dma_addr;
  17525. + ring->buf[i].desc->data = (u32) dma_addr;
  17526. + }
  17527. +
  17528. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  17529. + count++;
  17530. + }
  17531. +
  17532. + /* flush descriptors */
  17533. + wmb();
  17534. +
  17535. + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count);
  17536. +
  17537. + return count;
  17538. +}
  17539. +
  17540. +static int ag71xx_rings_init(struct ag71xx *ag)
  17541. +{
  17542. + int ret;
  17543. +
  17544. + ret = ag71xx_ring_alloc(&ag->tx_ring);
  17545. + if (ret)
  17546. + return ret;
  17547. +
  17548. + ag71xx_ring_tx_init(ag);
  17549. +
  17550. + ret = ag71xx_ring_alloc(&ag->rx_ring);
  17551. + if (ret)
  17552. + return ret;
  17553. +
  17554. + ret = ag71xx_ring_rx_init(ag);
  17555. + return ret;
  17556. +}
  17557. +
  17558. +static void ag71xx_rings_cleanup(struct ag71xx *ag)
  17559. +{
  17560. + ag71xx_ring_rx_clean(ag);
  17561. + ag71xx_ring_free(&ag->rx_ring);
  17562. +
  17563. + ag71xx_ring_tx_clean(ag);
  17564. + ag71xx_ring_free(&ag->tx_ring);
  17565. +}
  17566. +
  17567. +static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
  17568. +{
  17569. + switch (ag->speed) {
  17570. + case SPEED_1000:
  17571. + return "1000";
  17572. + case SPEED_100:
  17573. + return "100";
  17574. + case SPEED_10:
  17575. + return "10";
  17576. + }
  17577. +
  17578. + return "?";
  17579. +}
  17580. +
  17581. +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
  17582. +{
  17583. + u32 t;
  17584. +
  17585. + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
  17586. + | (((u32) mac[3]) << 8) | ((u32) mac[2]);
  17587. +
  17588. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
  17589. +
  17590. + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
  17591. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
  17592. +}
  17593. +
  17594. +static void ag71xx_dma_reset(struct ag71xx *ag)
  17595. +{
  17596. + u32 val;
  17597. + int i;
  17598. +
  17599. + ag71xx_dump_dma_regs(ag);
  17600. +
  17601. + /* stop RX and TX */
  17602. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  17603. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  17604. +
  17605. + /*
  17606. + * give the hardware some time to really stop all rx/tx activity
  17607. + * clearing the descriptors too early causes random memory corruption
  17608. + */
  17609. + mdelay(1);
  17610. +
  17611. + /* clear descriptor addresses */
  17612. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma);
  17613. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma);
  17614. +
  17615. + /* clear pending RX/TX interrupts */
  17616. + for (i = 0; i < 256; i++) {
  17617. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  17618. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  17619. + }
  17620. +
  17621. + /* clear pending errors */
  17622. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
  17623. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
  17624. +
  17625. + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  17626. + if (val)
  17627. + printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
  17628. + ag->dev->name, val);
  17629. +
  17630. + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  17631. +
  17632. + /* mask out reserved bits */
  17633. + val &= ~0xff000000;
  17634. +
  17635. + if (val)
  17636. + printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
  17637. + ag->dev->name, val);
  17638. +
  17639. + ag71xx_dump_dma_regs(ag);
  17640. +}
  17641. +
  17642. +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
  17643. + MAC_CFG1_SRX | MAC_CFG1_STX)
  17644. +
  17645. +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
  17646. +
  17647. +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
  17648. + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
  17649. + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
  17650. + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
  17651. + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
  17652. + FIFO_CFG4_VT)
  17653. +
  17654. +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
  17655. + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
  17656. + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
  17657. + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
  17658. + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
  17659. + FIFO_CFG5_17 | FIFO_CFG5_SF)
  17660. +
  17661. +static void ag71xx_hw_stop(struct ag71xx *ag)
  17662. +{
  17663. + /* disable all interrupts and stop the rx/tx engine */
  17664. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
  17665. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  17666. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  17667. +}
  17668. +
  17669. +static void ag71xx_hw_setup(struct ag71xx *ag)
  17670. +{
  17671. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  17672. +
  17673. + /* setup MAC configuration registers */
  17674. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
  17675. +
  17676. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
  17677. + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
  17678. +
  17679. + /* setup max frame length */
  17680. + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
  17681. +
  17682. + /* setup MII interface type */
  17683. + ag71xx_mii_ctrl_set_if(ag, pdata->mii_if);
  17684. +
  17685. + /* setup FIFO configuration registers */
  17686. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
  17687. + if (pdata->is_ar724x) {
  17688. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1);
  17689. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2);
  17690. + } else {
  17691. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
  17692. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
  17693. + }
  17694. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
  17695. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
  17696. +}
  17697. +
  17698. +static void ag71xx_hw_init(struct ag71xx *ag)
  17699. +{
  17700. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  17701. + u32 reset_mask = pdata->reset_bit;
  17702. +
  17703. + ag71xx_hw_stop(ag);
  17704. +
  17705. + if (pdata->is_ar724x) {
  17706. + u32 reset_phy = reset_mask;
  17707. +
  17708. + reset_phy &= RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY;
  17709. + reset_mask &= ~(RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY);
  17710. +
  17711. + ar71xx_device_stop(reset_phy);
  17712. + mdelay(50);
  17713. + ar71xx_device_start(reset_phy);
  17714. + mdelay(200);
  17715. + }
  17716. +
  17717. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
  17718. + udelay(20);
  17719. +
  17720. + ar71xx_device_stop(reset_mask);
  17721. + mdelay(100);
  17722. + ar71xx_device_start(reset_mask);
  17723. + mdelay(200);
  17724. +
  17725. + ag71xx_hw_setup(ag);
  17726. +
  17727. + ag71xx_dma_reset(ag);
  17728. +}
  17729. +
  17730. +static void ag71xx_fast_reset(struct ag71xx *ag)
  17731. +{
  17732. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  17733. + struct net_device *dev = ag->dev;
  17734. + u32 reset_mask = pdata->reset_bit;
  17735. + u32 rx_ds, tx_ds;
  17736. + u32 mii_reg;
  17737. +
  17738. + reset_mask &= RESET_MODULE_GE0_MAC | RESET_MODULE_GE1_MAC;
  17739. +
  17740. + mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG);
  17741. + rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC);
  17742. + tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC);
  17743. +
  17744. + ar71xx_device_stop(reset_mask);
  17745. + udelay(10);
  17746. + ar71xx_device_start(reset_mask);
  17747. + udelay(10);
  17748. +
  17749. + ag71xx_dma_reset(ag);
  17750. + ag71xx_hw_setup(ag);
  17751. +
  17752. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds);
  17753. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds);
  17754. + ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg);
  17755. +
  17756. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  17757. +}
  17758. +
  17759. +static void ag71xx_hw_start(struct ag71xx *ag)
  17760. +{
  17761. + /* start RX engine */
  17762. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  17763. +
  17764. + /* enable interrupts */
  17765. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
  17766. +}
  17767. +
  17768. +void ag71xx_link_adjust(struct ag71xx *ag)
  17769. +{
  17770. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  17771. + u32 cfg2;
  17772. + u32 ifctl;
  17773. + u32 fifo5;
  17774. + u32 mii_speed;
  17775. +
  17776. + if (!ag->link) {
  17777. + ag71xx_hw_stop(ag);
  17778. + netif_carrier_off(ag->dev);
  17779. + if (netif_msg_link(ag))
  17780. + printk(KERN_INFO "%s: link down\n", ag->dev->name);
  17781. + return;
  17782. + }
  17783. +
  17784. + if (pdata->is_ar724x)
  17785. + ag71xx_fast_reset(ag);
  17786. +
  17787. + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
  17788. + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
  17789. + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
  17790. +
  17791. + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
  17792. + ifctl &= ~(MAC_IFCTL_SPEED);
  17793. +
  17794. + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
  17795. + fifo5 &= ~FIFO_CFG5_BM;
  17796. +
  17797. + switch (ag->speed) {
  17798. + case SPEED_1000:
  17799. + mii_speed = MII_CTRL_SPEED_1000;
  17800. + cfg2 |= MAC_CFG2_IF_1000;
  17801. + fifo5 |= FIFO_CFG5_BM;
  17802. + break;
  17803. + case SPEED_100:
  17804. + mii_speed = MII_CTRL_SPEED_100;
  17805. + cfg2 |= MAC_CFG2_IF_10_100;
  17806. + ifctl |= MAC_IFCTL_SPEED;
  17807. + break;
  17808. + case SPEED_10:
  17809. + mii_speed = MII_CTRL_SPEED_10;
  17810. + cfg2 |= MAC_CFG2_IF_10_100;
  17811. + break;
  17812. + default:
  17813. + BUG();
  17814. + return;
  17815. + }
  17816. +
  17817. + if (pdata->is_ar91xx)
  17818. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
  17819. + else if (pdata->is_ar724x)
  17820. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3);
  17821. + else
  17822. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
  17823. +
  17824. + if (pdata->set_pll)
  17825. + pdata->set_pll(ag->speed);
  17826. +
  17827. + ag71xx_mii_ctrl_set_speed(ag, mii_speed);
  17828. +
  17829. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
  17830. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
  17831. + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
  17832. + ag71xx_hw_start(ag);
  17833. +
  17834. + netif_carrier_on(ag->dev);
  17835. + if (netif_msg_link(ag))
  17836. + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
  17837. + ag->dev->name,
  17838. + ag71xx_speed_str(ag),
  17839. + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half");
  17840. +
  17841. + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
  17842. + ag->dev->name,
  17843. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  17844. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  17845. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  17846. +
  17847. + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
  17848. + ag->dev->name,
  17849. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  17850. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  17851. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  17852. +
  17853. + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
  17854. + ag->dev->name,
  17855. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  17856. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  17857. + ag71xx_mii_ctrl_rr(ag));
  17858. +}
  17859. +
  17860. +static int ag71xx_open(struct net_device *dev)
  17861. +{
  17862. + struct ag71xx *ag = netdev_priv(dev);
  17863. + int ret;
  17864. +
  17865. + ret = ag71xx_rings_init(ag);
  17866. + if (ret)
  17867. + goto err;
  17868. +
  17869. + napi_enable(&ag->napi);
  17870. +
  17871. + netif_carrier_off(dev);
  17872. + ag71xx_phy_start(ag);
  17873. +
  17874. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);
  17875. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma);
  17876. +
  17877. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  17878. +
  17879. + netif_start_queue(dev);
  17880. +
  17881. + return 0;
  17882. +
  17883. +err:
  17884. + ag71xx_rings_cleanup(ag);
  17885. + return ret;
  17886. +}
  17887. +
  17888. +static int ag71xx_stop(struct net_device *dev)
  17889. +{
  17890. + struct ag71xx *ag = netdev_priv(dev);
  17891. + unsigned long flags;
  17892. +
  17893. + netif_carrier_off(dev);
  17894. + ag71xx_phy_stop(ag);
  17895. +
  17896. + spin_lock_irqsave(&ag->lock, flags);
  17897. +
  17898. + netif_stop_queue(dev);
  17899. +
  17900. + ag71xx_hw_stop(ag);
  17901. + ag71xx_dma_reset(ag);
  17902. +
  17903. + napi_disable(&ag->napi);
  17904. + del_timer_sync(&ag->oom_timer);
  17905. +
  17906. + spin_unlock_irqrestore(&ag->lock, flags);
  17907. +
  17908. + ag71xx_rings_cleanup(ag);
  17909. +
  17910. + return 0;
  17911. +}
  17912. +
  17913. +static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
  17914. + struct net_device *dev)
  17915. +{
  17916. + struct ag71xx *ag = netdev_priv(dev);
  17917. + struct ag71xx_ring *ring = &ag->tx_ring;
  17918. + struct ag71xx_desc *desc;
  17919. + dma_addr_t dma_addr;
  17920. + int i;
  17921. +
  17922. + i = ring->curr % ring->size;
  17923. + desc = ring->buf[i].desc;
  17924. +
  17925. + if (!ag71xx_desc_empty(desc))
  17926. + goto err_drop;
  17927. +
  17928. + if (ag71xx_has_ar8216(ag))
  17929. + ag71xx_add_ar8216_header(ag, skb);
  17930. +
  17931. + if (skb->len <= 0) {
  17932. + DBG("%s: packet len is too small\n", ag->dev->name);
  17933. + goto err_drop;
  17934. + }
  17935. +
  17936. + dma_addr = dma_map_single(&dev->dev, skb->data, skb->len,
  17937. + DMA_TO_DEVICE);
  17938. +
  17939. + ring->buf[i].skb = skb;
  17940. + ring->buf[i].timestamp = jiffies;
  17941. +
  17942. + /* setup descriptor fields */
  17943. + desc->data = (u32) dma_addr;
  17944. + desc->ctrl = (skb->len & DESC_PKTLEN_M);
  17945. +
  17946. + /* flush descriptor */
  17947. + wmb();
  17948. +
  17949. + ring->curr++;
  17950. + if (ring->curr == (ring->dirty + ring->size)) {
  17951. + DBG("%s: tx queue full\n", ag->dev->name);
  17952. + netif_stop_queue(dev);
  17953. + }
  17954. +
  17955. + DBG("%s: packet injected into TX queue\n", ag->dev->name);
  17956. +
  17957. + /* enable TX engine */
  17958. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
  17959. +
  17960. + return NETDEV_TX_OK;
  17961. +
  17962. +err_drop:
  17963. + dev->stats.tx_dropped++;
  17964. +
  17965. + dev_kfree_skb(skb);
  17966. + return NETDEV_TX_OK;
  17967. +}
  17968. +
  17969. +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  17970. +{
  17971. + struct ag71xx *ag = netdev_priv(dev);
  17972. + int ret;
  17973. +
  17974. + switch (cmd) {
  17975. + case SIOCETHTOOL:
  17976. + if (ag->phy_dev == NULL)
  17977. + break;
  17978. +
  17979. + spin_lock_irq(&ag->lock);
  17980. + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data);
  17981. + spin_unlock_irq(&ag->lock);
  17982. + return ret;
  17983. +
  17984. + case SIOCSIFHWADDR:
  17985. + if (copy_from_user
  17986. + (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
  17987. + return -EFAULT;
  17988. + return 0;
  17989. +
  17990. + case SIOCGIFHWADDR:
  17991. + if (copy_to_user
  17992. + (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
  17993. + return -EFAULT;
  17994. + return 0;
  17995. +
  17996. + case SIOCGMIIPHY:
  17997. + case SIOCGMIIREG:
  17998. + case SIOCSMIIREG:
  17999. + if (ag->phy_dev == NULL)
  18000. + break;
  18001. +
  18002. + return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
  18003. +
  18004. + default:
  18005. + break;
  18006. + }
  18007. +
  18008. + return -EOPNOTSUPP;
  18009. +}
  18010. +
  18011. +static void ag71xx_oom_timer_handler(unsigned long data)
  18012. +{
  18013. + struct net_device *dev = (struct net_device *) data;
  18014. + struct ag71xx *ag = netdev_priv(dev);
  18015. +
  18016. + napi_schedule(&ag->napi);
  18017. +}
  18018. +
  18019. +static void ag71xx_tx_timeout(struct net_device *dev)
  18020. +{
  18021. + struct ag71xx *ag = netdev_priv(dev);
  18022. +
  18023. + if (netif_msg_tx_err(ag))
  18024. + printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
  18025. +
  18026. + schedule_work(&ag->restart_work);
  18027. +}
  18028. +
  18029. +static void ag71xx_restart_work_func(struct work_struct *work)
  18030. +{
  18031. + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
  18032. +
  18033. + if (ag71xx_get_pdata(ag)->is_ar724x) {
  18034. + ag->link = 0;
  18035. + ag71xx_link_adjust(ag);
  18036. + return;
  18037. + }
  18038. +
  18039. + ag71xx_stop(ag->dev);
  18040. + ag71xx_open(ag->dev);
  18041. +}
  18042. +
  18043. +static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp)
  18044. +{
  18045. + u32 rx_sm, tx_sm, rx_fd;
  18046. +
  18047. + if (likely(time_before(jiffies, timestamp + HZ/10)))
  18048. + return false;
  18049. +
  18050. + if (!netif_carrier_ok(ag->dev))
  18051. + return false;
  18052. +
  18053. + rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM);
  18054. + if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6)
  18055. + return true;
  18056. +
  18057. + tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM);
  18058. + rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH);
  18059. + if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) &&
  18060. + ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0)
  18061. + return true;
  18062. +
  18063. + return false;
  18064. +}
  18065. +
  18066. +static int ag71xx_tx_packets(struct ag71xx *ag)
  18067. +{
  18068. + struct ag71xx_ring *ring = &ag->tx_ring;
  18069. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18070. + int sent;
  18071. +
  18072. + DBG("%s: processing TX ring\n", ag->dev->name);
  18073. +
  18074. + sent = 0;
  18075. + while (ring->dirty != ring->curr) {
  18076. + unsigned int i = ring->dirty % ring->size;
  18077. + struct ag71xx_desc *desc = ring->buf[i].desc;
  18078. + struct sk_buff *skb = ring->buf[i].skb;
  18079. +
  18080. + if (!ag71xx_desc_empty(desc)) {
  18081. + if (pdata->is_ar7240 &&
  18082. + ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp))
  18083. + schedule_work(&ag->restart_work);
  18084. + break;
  18085. + }
  18086. +
  18087. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  18088. +
  18089. + ag->dev->stats.tx_bytes += skb->len;
  18090. + ag->dev->stats.tx_packets++;
  18091. +
  18092. + dev_kfree_skb_any(skb);
  18093. + ring->buf[i].skb = NULL;
  18094. +
  18095. + ring->dirty++;
  18096. + sent++;
  18097. + }
  18098. +
  18099. + DBG("%s: %d packets sent out\n", ag->dev->name, sent);
  18100. +
  18101. + if ((ring->curr - ring->dirty) < (ring->size * 3) / 4)
  18102. + netif_wake_queue(ag->dev);
  18103. +
  18104. + return sent;
  18105. +}
  18106. +
  18107. +static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
  18108. +{
  18109. + struct net_device *dev = ag->dev;
  18110. + struct ag71xx_ring *ring = &ag->rx_ring;
  18111. + int done = 0;
  18112. +
  18113. + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n",
  18114. + dev->name, limit, ring->curr, ring->dirty);
  18115. +
  18116. + while (done < limit) {
  18117. + unsigned int i = ring->curr % ring->size;
  18118. + struct ag71xx_desc *desc = ring->buf[i].desc;
  18119. + struct sk_buff *skb;
  18120. + int pktlen;
  18121. + int err = 0;
  18122. +
  18123. + if (ag71xx_desc_empty(desc))
  18124. + break;
  18125. +
  18126. + if ((ring->dirty + ring->size) == ring->curr) {
  18127. + ag71xx_assert(0);
  18128. + break;
  18129. + }
  18130. +
  18131. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  18132. +
  18133. + skb = ring->buf[i].skb;
  18134. + pktlen = ag71xx_desc_pktlen(desc);
  18135. + pktlen -= ETH_FCS_LEN;
  18136. +
  18137. + dma_unmap_single(&dev->dev, ring->buf[i].dma_addr,
  18138. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  18139. +
  18140. + dev->last_rx = jiffies;
  18141. + dev->stats.rx_packets++;
  18142. + dev->stats.rx_bytes += pktlen;
  18143. +
  18144. + skb_put(skb, pktlen);
  18145. + if (ag71xx_has_ar8216(ag))
  18146. + err = ag71xx_remove_ar8216_header(ag, skb, pktlen);
  18147. +
  18148. + if (err) {
  18149. + dev->stats.rx_dropped++;
  18150. + kfree_skb(skb);
  18151. + } else {
  18152. + skb->dev = dev;
  18153. + skb->ip_summed = CHECKSUM_NONE;
  18154. + if (ag->phy_dev) {
  18155. + ag->phy_dev->netif_receive_skb(skb);
  18156. + } else {
  18157. + skb->protocol = eth_type_trans(skb, dev);
  18158. + netif_receive_skb(skb);
  18159. + }
  18160. + }
  18161. +
  18162. + ring->buf[i].skb = NULL;
  18163. + done++;
  18164. +
  18165. + ring->curr++;
  18166. + }
  18167. +
  18168. + ag71xx_ring_rx_refill(ag);
  18169. +
  18170. + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n",
  18171. + dev->name, ring->curr, ring->dirty, done);
  18172. +
  18173. + return done;
  18174. +}
  18175. +
  18176. +static int ag71xx_poll(struct napi_struct *napi, int limit)
  18177. +{
  18178. + struct ag71xx *ag = container_of(napi, struct ag71xx, napi);
  18179. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18180. + struct net_device *dev = ag->dev;
  18181. + struct ag71xx_ring *rx_ring;
  18182. + unsigned long flags;
  18183. + u32 status;
  18184. + int tx_done;
  18185. + int rx_done;
  18186. +
  18187. + pdata->ddr_flush();
  18188. + tx_done = ag71xx_tx_packets(ag);
  18189. +
  18190. + DBG("%s: processing RX ring\n", dev->name);
  18191. + rx_done = ag71xx_rx_packets(ag, limit);
  18192. +
  18193. + ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done);
  18194. +
  18195. + rx_ring = &ag->rx_ring;
  18196. + if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL)
  18197. + goto oom;
  18198. +
  18199. + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  18200. + if (unlikely(status & RX_STATUS_OF)) {
  18201. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
  18202. + dev->stats.rx_fifo_errors++;
  18203. +
  18204. + /* restart RX */
  18205. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  18206. + }
  18207. +
  18208. + if (rx_done < limit) {
  18209. + if (status & RX_STATUS_PR)
  18210. + goto more;
  18211. +
  18212. + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  18213. + if (status & TX_STATUS_PS)
  18214. + goto more;
  18215. +
  18216. + DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n",
  18217. + dev->name, rx_done, tx_done, limit);
  18218. +
  18219. + napi_complete(napi);
  18220. +
  18221. + /* enable interrupts */
  18222. + spin_lock_irqsave(&ag->lock, flags);
  18223. + ag71xx_int_enable(ag, AG71XX_INT_POLL);
  18224. + spin_unlock_irqrestore(&ag->lock, flags);
  18225. + return rx_done;
  18226. + }
  18227. +
  18228. +more:
  18229. + DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n",
  18230. + dev->name, rx_done, tx_done, limit);
  18231. + return rx_done;
  18232. +
  18233. +oom:
  18234. + if (netif_msg_rx_err(ag))
  18235. + printk(KERN_DEBUG "%s: out of memory\n", dev->name);
  18236. +
  18237. + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
  18238. + napi_complete(napi);
  18239. + return 0;
  18240. +}
  18241. +
  18242. +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
  18243. +{
  18244. + struct net_device *dev = dev_id;
  18245. + struct ag71xx *ag = netdev_priv(dev);
  18246. + u32 status;
  18247. +
  18248. + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
  18249. + ag71xx_dump_intr(ag, "raw", status);
  18250. +
  18251. + if (unlikely(!status))
  18252. + return IRQ_NONE;
  18253. +
  18254. + if (unlikely(status & AG71XX_INT_ERR)) {
  18255. + if (status & AG71XX_INT_TX_BE) {
  18256. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE);
  18257. + dev_err(&dev->dev, "TX BUS error\n");
  18258. + }
  18259. + if (status & AG71XX_INT_RX_BE) {
  18260. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE);
  18261. + dev_err(&dev->dev, "RX BUS error\n");
  18262. + }
  18263. + }
  18264. +
  18265. + if (likely(status & AG71XX_INT_POLL)) {
  18266. + ag71xx_int_disable(ag, AG71XX_INT_POLL);
  18267. + DBG("%s: enable polling mode\n", dev->name);
  18268. + napi_schedule(&ag->napi);
  18269. + }
  18270. +
  18271. + ag71xx_debugfs_update_int_stats(ag, status);
  18272. +
  18273. + return IRQ_HANDLED;
  18274. +}
  18275. +
  18276. +static void ag71xx_set_multicast_list(struct net_device *dev)
  18277. +{
  18278. + /* TODO */
  18279. +}
  18280. +
  18281. +#ifdef CONFIG_NET_POLL_CONTROLLER
  18282. +/*
  18283. + * Polling 'interrupt' - used by things like netconsole to send skbs
  18284. + * without having to re-enable interrupts. It's not called while
  18285. + * the interrupt routine is executing.
  18286. + */
  18287. +static void ag71xx_netpoll(struct net_device *dev)
  18288. +{
  18289. + disable_irq(dev->irq);
  18290. + ag71xx_interrupt(dev->irq, dev);
  18291. + enable_irq(dev->irq);
  18292. +}
  18293. +#endif
  18294. +
  18295. +static const struct net_device_ops ag71xx_netdev_ops = {
  18296. + .ndo_open = ag71xx_open,
  18297. + .ndo_stop = ag71xx_stop,
  18298. + .ndo_start_xmit = ag71xx_hard_start_xmit,
  18299. + .ndo_set_multicast_list = ag71xx_set_multicast_list,
  18300. + .ndo_do_ioctl = ag71xx_do_ioctl,
  18301. + .ndo_tx_timeout = ag71xx_tx_timeout,
  18302. + .ndo_change_mtu = eth_change_mtu,
  18303. + .ndo_set_mac_address = eth_mac_addr,
  18304. + .ndo_validate_addr = eth_validate_addr,
  18305. +#ifdef CONFIG_NET_POLL_CONTROLLER
  18306. + .ndo_poll_controller = ag71xx_netpoll,
  18307. +#endif
  18308. +};
  18309. +
  18310. +static int __devinit ag71xx_probe(struct platform_device *pdev)
  18311. +{
  18312. + struct net_device *dev;
  18313. + struct resource *res;
  18314. + struct ag71xx *ag;
  18315. + struct ag71xx_platform_data *pdata;
  18316. + int err;
  18317. +
  18318. + pdata = pdev->dev.platform_data;
  18319. + if (!pdata) {
  18320. + dev_err(&pdev->dev, "no platform data specified\n");
  18321. + err = -ENXIO;
  18322. + goto err_out;
  18323. + }
  18324. +
  18325. + if (pdata->mii_bus_dev == NULL) {
  18326. + dev_err(&pdev->dev, "no MII bus device specified\n");
  18327. + err = -EINVAL;
  18328. + goto err_out;
  18329. + }
  18330. +
  18331. + dev = alloc_etherdev(sizeof(*ag));
  18332. + if (!dev) {
  18333. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  18334. + err = -ENOMEM;
  18335. + goto err_out;
  18336. + }
  18337. +
  18338. + SET_NETDEV_DEV(dev, &pdev->dev);
  18339. +
  18340. + ag = netdev_priv(dev);
  18341. + ag->pdev = pdev;
  18342. + ag->dev = dev;
  18343. + ag->msg_enable = netif_msg_init(ag71xx_msg_level,
  18344. + AG71XX_DEFAULT_MSG_ENABLE);
  18345. + spin_lock_init(&ag->lock);
  18346. +
  18347. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base");
  18348. + if (!res) {
  18349. + dev_err(&pdev->dev, "no mac_base resource found\n");
  18350. + err = -ENXIO;
  18351. + goto err_out;
  18352. + }
  18353. +
  18354. + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1);
  18355. + if (!ag->mac_base) {
  18356. + dev_err(&pdev->dev, "unable to ioremap mac_base\n");
  18357. + err = -ENOMEM;
  18358. + goto err_free_dev;
  18359. + }
  18360. +
  18361. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl");
  18362. + if (!res) {
  18363. + dev_err(&pdev->dev, "no mii_ctrl resource found\n");
  18364. + err = -ENXIO;
  18365. + goto err_unmap_base;
  18366. + }
  18367. +
  18368. + ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1);
  18369. + if (!ag->mii_ctrl) {
  18370. + dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n");
  18371. + err = -ENOMEM;
  18372. + goto err_unmap_base;
  18373. + }
  18374. +
  18375. + dev->irq = platform_get_irq(pdev, 0);
  18376. + err = request_irq(dev->irq, ag71xx_interrupt,
  18377. + IRQF_DISABLED,
  18378. + dev->name, dev);
  18379. + if (err) {
  18380. + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
  18381. + goto err_unmap_mii_ctrl;
  18382. + }
  18383. +
  18384. + dev->base_addr = (unsigned long)ag->mac_base;
  18385. + dev->netdev_ops = &ag71xx_netdev_ops;
  18386. + dev->ethtool_ops = &ag71xx_ethtool_ops;
  18387. +
  18388. + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
  18389. +
  18390. + init_timer(&ag->oom_timer);
  18391. + ag->oom_timer.data = (unsigned long) dev;
  18392. + ag->oom_timer.function = ag71xx_oom_timer_handler;
  18393. +
  18394. + ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT;
  18395. + ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT;
  18396. +
  18397. + ag->stop_desc = dma_alloc_coherent(NULL,
  18398. + sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL);
  18399. +
  18400. + if (!ag->stop_desc)
  18401. + goto err_free_irq;
  18402. +
  18403. + ag->stop_desc->data = 0;
  18404. + ag->stop_desc->ctrl = 0;
  18405. + ag->stop_desc->next = (u32) ag->stop_desc_dma;
  18406. +
  18407. + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
  18408. +
  18409. + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
  18410. +
  18411. + err = register_netdev(dev);
  18412. + if (err) {
  18413. + dev_err(&pdev->dev, "unable to register net device\n");
  18414. + goto err_free_desc;
  18415. + }
  18416. +
  18417. + printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n",
  18418. + dev->name, dev->base_addr, dev->irq);
  18419. +
  18420. + ag71xx_dump_regs(ag);
  18421. +
  18422. + ag71xx_hw_init(ag);
  18423. +
  18424. + ag71xx_dump_regs(ag);
  18425. +
  18426. + err = ag71xx_phy_connect(ag);
  18427. + if (err)
  18428. + goto err_unregister_netdev;
  18429. +
  18430. + err = ag71xx_debugfs_init(ag);
  18431. + if (err)
  18432. + goto err_phy_disconnect;
  18433. +
  18434. + platform_set_drvdata(pdev, dev);
  18435. +
  18436. + return 0;
  18437. +
  18438. +err_phy_disconnect:
  18439. + ag71xx_phy_disconnect(ag);
  18440. +err_unregister_netdev:
  18441. + unregister_netdev(dev);
  18442. +err_free_desc:
  18443. + dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc,
  18444. + ag->stop_desc_dma);
  18445. +err_free_irq:
  18446. + free_irq(dev->irq, dev);
  18447. +err_unmap_mii_ctrl:
  18448. + iounmap(ag->mii_ctrl);
  18449. +err_unmap_base:
  18450. + iounmap(ag->mac_base);
  18451. +err_free_dev:
  18452. + kfree(dev);
  18453. +err_out:
  18454. + platform_set_drvdata(pdev, NULL);
  18455. + return err;
  18456. +}
  18457. +
  18458. +static int __devexit ag71xx_remove(struct platform_device *pdev)
  18459. +{
  18460. + struct net_device *dev = platform_get_drvdata(pdev);
  18461. +
  18462. + if (dev) {
  18463. + struct ag71xx *ag = netdev_priv(dev);
  18464. +
  18465. + ag71xx_debugfs_exit(ag);
  18466. + ag71xx_phy_disconnect(ag);
  18467. + unregister_netdev(dev);
  18468. + free_irq(dev->irq, dev);
  18469. + iounmap(ag->mii_ctrl);
  18470. + iounmap(ag->mac_base);
  18471. + kfree(dev);
  18472. + platform_set_drvdata(pdev, NULL);
  18473. + }
  18474. +
  18475. + return 0;
  18476. +}
  18477. +
  18478. +static struct platform_driver ag71xx_driver = {
  18479. + .probe = ag71xx_probe,
  18480. + .remove = __exit_p(ag71xx_remove),
  18481. + .driver = {
  18482. + .name = AG71XX_DRV_NAME,
  18483. + }
  18484. +};
  18485. +
  18486. +static int __init ag71xx_module_init(void)
  18487. +{
  18488. + int ret;
  18489. +
  18490. + ret = ag71xx_debugfs_root_init();
  18491. + if (ret)
  18492. + goto err_out;
  18493. +
  18494. + ret = ag71xx_mdio_driver_init();
  18495. + if (ret)
  18496. + goto err_debugfs_exit;
  18497. +
  18498. + ret = platform_driver_register(&ag71xx_driver);
  18499. + if (ret)
  18500. + goto err_mdio_exit;
  18501. +
  18502. + return 0;
  18503. +
  18504. +err_mdio_exit:
  18505. + ag71xx_mdio_driver_exit();
  18506. +err_debugfs_exit:
  18507. + ag71xx_debugfs_root_exit();
  18508. +err_out:
  18509. + return ret;
  18510. +}
  18511. +
  18512. +static void __exit ag71xx_module_exit(void)
  18513. +{
  18514. + platform_driver_unregister(&ag71xx_driver);
  18515. + ag71xx_mdio_driver_exit();
  18516. + ag71xx_debugfs_root_exit();
  18517. +}
  18518. +
  18519. +module_init(ag71xx_module_init);
  18520. +module_exit(ag71xx_module_exit);
  18521. +
  18522. +MODULE_VERSION(AG71XX_DRV_VERSION);
  18523. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  18524. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  18525. +MODULE_LICENSE("GPL v2");
  18526. +MODULE_ALIAS("platform:" AG71XX_DRV_NAME);
  18527. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c
  18528. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100
  18529. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-08-24 18:17:24.000000000 +0200
  18530. @@ -0,0 +1,248 @@
  18531. +/*
  18532. + * Atheros AR71xx built-in ethernet mac driver
  18533. + *
  18534. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  18535. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  18536. + *
  18537. + * Based on Atheros' AG7100 driver
  18538. + *
  18539. + * This program is free software; you can redistribute it and/or modify it
  18540. + * under the terms of the GNU General Public License version 2 as published
  18541. + * by the Free Software Foundation.
  18542. + */
  18543. +
  18544. +#include "ag71xx.h"
  18545. +
  18546. +#define AG71XX_MDIO_RETRY 1000
  18547. +#define AG71XX_MDIO_DELAY 5
  18548. +
  18549. +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg,
  18550. + u32 value)
  18551. +{
  18552. + void __iomem *r;
  18553. +
  18554. + r = am->mdio_base + reg;
  18555. + __raw_writel(value, r);
  18556. +
  18557. + /* flush write */
  18558. + (void) __raw_readl(r);
  18559. +}
  18560. +
  18561. +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg)
  18562. +{
  18563. + return __raw_readl(am->mdio_base + reg);
  18564. +}
  18565. +
  18566. +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
  18567. +{
  18568. + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n",
  18569. + am->mii_bus->name,
  18570. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG),
  18571. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD),
  18572. + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR));
  18573. + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n",
  18574. + am->mii_bus->name,
  18575. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL),
  18576. + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS),
  18577. + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
  18578. +}
  18579. +
  18580. +int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
  18581. +{
  18582. + int ret;
  18583. + int i;
  18584. +
  18585. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  18586. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  18587. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  18588. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ);
  18589. +
  18590. + i = AG71XX_MDIO_RETRY;
  18591. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  18592. + if (i-- == 0) {
  18593. + printk(KERN_ERR "%s: mii_read timed out\n",
  18594. + am->mii_bus->name);
  18595. + ret = 0xffff;
  18596. + goto out;
  18597. + }
  18598. + udelay(AG71XX_MDIO_DELAY);
  18599. + }
  18600. +
  18601. + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff;
  18602. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  18603. +
  18604. + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
  18605. +
  18606. +out:
  18607. + return ret;
  18608. +}
  18609. +
  18610. +void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val)
  18611. +{
  18612. + int i;
  18613. +
  18614. + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
  18615. +
  18616. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  18617. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  18618. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val);
  18619. +
  18620. + i = AG71XX_MDIO_RETRY;
  18621. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  18622. + if (i-- == 0) {
  18623. + printk(KERN_ERR "%s: mii_write timed out\n",
  18624. + am->mii_bus->name);
  18625. + break;
  18626. + }
  18627. + udelay(AG71XX_MDIO_DELAY);
  18628. + }
  18629. +}
  18630. +
  18631. +static int ag71xx_mdio_reset(struct mii_bus *bus)
  18632. +{
  18633. + struct ag71xx_mdio *am = bus->priv;
  18634. + u32 t;
  18635. +
  18636. + if (am->pdata->is_ar7240)
  18637. + t = MII_CFG_CLK_DIV_6;
  18638. + else
  18639. + t = MII_CFG_CLK_DIV_28;
  18640. +
  18641. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
  18642. + udelay(100);
  18643. +
  18644. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t);
  18645. + udelay(100);
  18646. +
  18647. + return 0;
  18648. +}
  18649. +
  18650. +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
  18651. +{
  18652. + struct ag71xx_mdio *am = bus->priv;
  18653. +
  18654. + if (am->pdata->is_ar7240)
  18655. + return ar7240sw_phy_read(bus, addr, reg);
  18656. + else
  18657. + return ag71xx_mdio_mii_read(am, addr, reg);
  18658. +}
  18659. +
  18660. +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
  18661. +{
  18662. + struct ag71xx_mdio *am = bus->priv;
  18663. +
  18664. + if (am->pdata->is_ar7240)
  18665. + ar7240sw_phy_write(bus, addr, reg, val);
  18666. + else
  18667. + ag71xx_mdio_mii_write(am, addr, reg, val);
  18668. + return 0;
  18669. +}
  18670. +
  18671. +static int __devinit ag71xx_mdio_probe(struct platform_device *pdev)
  18672. +{
  18673. + struct ag71xx_mdio_platform_data *pdata;
  18674. + struct ag71xx_mdio *am;
  18675. + struct resource *res;
  18676. + int i;
  18677. + int err;
  18678. +
  18679. + pdata = pdev->dev.platform_data;
  18680. + if (!pdata) {
  18681. + dev_err(&pdev->dev, "no platform data specified\n");
  18682. + return -EINVAL;
  18683. + }
  18684. +
  18685. + am = kzalloc(sizeof(*am), GFP_KERNEL);
  18686. + if (!am) {
  18687. + err = -ENOMEM;
  18688. + goto err_out;
  18689. + }
  18690. +
  18691. + am->pdata = pdata;
  18692. +
  18693. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  18694. + if (!res) {
  18695. + dev_err(&pdev->dev, "no iomem resource found\n");
  18696. + err = -ENXIO;
  18697. + goto err_out;
  18698. + }
  18699. +
  18700. + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);
  18701. + if (!am->mdio_base) {
  18702. + dev_err(&pdev->dev, "unable to ioremap registers\n");
  18703. + err = -ENOMEM;
  18704. + goto err_free_mdio;
  18705. + }
  18706. +
  18707. + am->mii_bus = mdiobus_alloc();
  18708. + if (am->mii_bus == NULL) {
  18709. + err = -ENOMEM;
  18710. + goto err_iounmap;
  18711. + }
  18712. +
  18713. + am->mii_bus->name = "ag71xx_mdio";
  18714. + am->mii_bus->read = ag71xx_mdio_read;
  18715. + am->mii_bus->write = ag71xx_mdio_write;
  18716. + am->mii_bus->reset = ag71xx_mdio_reset;
  18717. + am->mii_bus->irq = am->mii_irq;
  18718. + am->mii_bus->priv = am;
  18719. + am->mii_bus->parent = &pdev->dev;
  18720. + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
  18721. + am->mii_bus->phy_mask = pdata->phy_mask;
  18722. +
  18723. + for (i = 0; i < PHY_MAX_ADDR; i++)
  18724. + am->mii_irq[i] = PHY_POLL;
  18725. +
  18726. + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0);
  18727. +
  18728. + err = mdiobus_register(am->mii_bus);
  18729. + if (err)
  18730. + goto err_free_bus;
  18731. +
  18732. + ag71xx_mdio_dump_regs(am);
  18733. +
  18734. + platform_set_drvdata(pdev, am);
  18735. + return 0;
  18736. +
  18737. +err_free_bus:
  18738. + mdiobus_free(am->mii_bus);
  18739. +err_iounmap:
  18740. + iounmap(am->mdio_base);
  18741. +err_free_mdio:
  18742. + kfree(am);
  18743. +err_out:
  18744. + return err;
  18745. +}
  18746. +
  18747. +static int __devexit ag71xx_mdio_remove(struct platform_device *pdev)
  18748. +{
  18749. + struct ag71xx_mdio *am = platform_get_drvdata(pdev);
  18750. +
  18751. + if (am) {
  18752. + mdiobus_unregister(am->mii_bus);
  18753. + mdiobus_free(am->mii_bus);
  18754. + iounmap(am->mdio_base);
  18755. + kfree(am);
  18756. + platform_set_drvdata(pdev, NULL);
  18757. + }
  18758. +
  18759. + return 0;
  18760. +}
  18761. +
  18762. +static struct platform_driver ag71xx_mdio_driver = {
  18763. + .probe = ag71xx_mdio_probe,
  18764. + .remove = __exit_p(ag71xx_mdio_remove),
  18765. + .driver = {
  18766. + .name = "ag71xx-mdio",
  18767. + }
  18768. +};
  18769. +
  18770. +int __init ag71xx_mdio_driver_init(void)
  18771. +{
  18772. + return platform_driver_register(&ag71xx_mdio_driver);
  18773. +}
  18774. +
  18775. +void ag71xx_mdio_driver_exit(void)
  18776. +{
  18777. + platform_driver_unregister(&ag71xx_mdio_driver);
  18778. +}
  18779. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c
  18780. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100
  18781. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-08-24 18:17:24.000000000 +0200
  18782. @@ -0,0 +1,228 @@
  18783. +/*
  18784. + * Atheros AR71xx built-in ethernet mac driver
  18785. + *
  18786. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  18787. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  18788. + *
  18789. + * Based on Atheros' AG7100 driver
  18790. + *
  18791. + * This program is free software; you can redistribute it and/or modify it
  18792. + * under the terms of the GNU General Public License version 2 as published
  18793. + * by the Free Software Foundation.
  18794. + */
  18795. +
  18796. +#include "ag71xx.h"
  18797. +
  18798. +static void ag71xx_phy_link_adjust(struct net_device *dev)
  18799. +{
  18800. + struct ag71xx *ag = netdev_priv(dev);
  18801. + struct phy_device *phydev = ag->phy_dev;
  18802. + unsigned long flags;
  18803. + int status_change = 0;
  18804. +
  18805. + spin_lock_irqsave(&ag->lock, flags);
  18806. +
  18807. + if (phydev->link) {
  18808. + if (ag->duplex != phydev->duplex
  18809. + || ag->speed != phydev->speed) {
  18810. + status_change = 1;
  18811. + }
  18812. + }
  18813. +
  18814. + if (phydev->link != ag->link)
  18815. + status_change = 1;
  18816. +
  18817. + ag->link = phydev->link;
  18818. + ag->duplex = phydev->duplex;
  18819. + ag->speed = phydev->speed;
  18820. +
  18821. + if (status_change)
  18822. + ag71xx_link_adjust(ag);
  18823. +
  18824. + spin_unlock_irqrestore(&ag->lock, flags);
  18825. +}
  18826. +
  18827. +void ag71xx_phy_start(struct ag71xx *ag)
  18828. +{
  18829. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18830. +
  18831. + if (ag->phy_dev) {
  18832. + phy_start(ag->phy_dev);
  18833. + } else if (pdata->has_ar7240_switch) {
  18834. + ag71xx_ar7240_start(ag);
  18835. + } else {
  18836. + ag->link = 1;
  18837. + ag71xx_link_adjust(ag);
  18838. + }
  18839. +}
  18840. +
  18841. +void ag71xx_phy_stop(struct ag71xx *ag)
  18842. +{
  18843. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18844. +
  18845. + if (ag->phy_dev) {
  18846. + phy_stop(ag->phy_dev);
  18847. + } else {
  18848. + if (pdata->has_ar7240_switch)
  18849. + ag71xx_ar7240_stop(ag);
  18850. + ag->link = 0;
  18851. + ag71xx_link_adjust(ag);
  18852. + }
  18853. +}
  18854. +
  18855. +static int ag71xx_phy_connect_fixed(struct ag71xx *ag)
  18856. +{
  18857. + struct net_device *dev = ag->dev;
  18858. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18859. + int ret = 0;
  18860. +
  18861. + /* use fixed settings */
  18862. + switch (pdata->speed) {
  18863. + case SPEED_10:
  18864. + case SPEED_100:
  18865. + case SPEED_1000:
  18866. + break;
  18867. + default:
  18868. + printk(KERN_ERR "%s: invalid speed specified\n", dev->name);
  18869. + ret = -EINVAL;
  18870. + break;
  18871. + }
  18872. +
  18873. + printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name);
  18874. +
  18875. + ag->duplex = pdata->duplex;
  18876. + ag->speed = pdata->speed;
  18877. +
  18878. + return ret;
  18879. +}
  18880. +
  18881. +static int ag71xx_phy_connect_multi(struct ag71xx *ag)
  18882. +{
  18883. + struct net_device *dev = ag->dev;
  18884. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18885. + struct phy_device *phydev = NULL;
  18886. + int phy_addr;
  18887. + int ret = 0;
  18888. +
  18889. + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
  18890. + if (!(pdata->phy_mask & (1 << phy_addr)))
  18891. + continue;
  18892. +
  18893. + if (ag->mii_bus->phy_map[phy_addr] == NULL)
  18894. + continue;
  18895. +
  18896. + DBG("%s: PHY found at %s, uid=%08x\n",
  18897. + dev->name,
  18898. + dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),
  18899. + ag->mii_bus->phy_map[phy_addr]->phy_id);
  18900. +
  18901. + if (phydev == NULL)
  18902. + phydev = ag->mii_bus->phy_map[phy_addr];
  18903. + }
  18904. +
  18905. + if (!phydev) {
  18906. + printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",
  18907. + dev->name, pdata->phy_mask);
  18908. + return -ENODEV;
  18909. + }
  18910. +
  18911. + ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev),
  18912. + &ag71xx_phy_link_adjust, 0,
  18913. + pdata->phy_if_mode);
  18914. +
  18915. + if (IS_ERR(ag->phy_dev)) {
  18916. + printk(KERN_ERR "%s: could not connect to PHY at %s\n",
  18917. + dev->name, dev_name(&phydev->dev));
  18918. + return PTR_ERR(ag->phy_dev);
  18919. + }
  18920. +
  18921. + /* mask with MAC supported features */
  18922. + if (pdata->has_gbit)
  18923. + phydev->supported &= PHY_GBIT_FEATURES;
  18924. + else
  18925. + phydev->supported &= PHY_BASIC_FEATURES;
  18926. +
  18927. + phydev->advertising = phydev->supported;
  18928. +
  18929. + printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
  18930. + dev->name, dev_name(&phydev->dev),
  18931. + phydev->phy_id, phydev->drv->name);
  18932. +
  18933. + ag->link = 0;
  18934. + ag->speed = 0;
  18935. + ag->duplex = -1;
  18936. +
  18937. + return ret;
  18938. +}
  18939. +
  18940. +static int dev_is_class(struct device *dev, void *class)
  18941. +{
  18942. + if (dev->class != NULL && !strcmp(dev->class->name, class))
  18943. + return 1;
  18944. +
  18945. + return 0;
  18946. +}
  18947. +
  18948. +static struct device *dev_find_class(struct device *parent, char *class)
  18949. +{
  18950. + if (dev_is_class(parent, class)) {
  18951. + get_device(parent);
  18952. + return parent;
  18953. + }
  18954. +
  18955. + return device_find_child(parent, class, dev_is_class);
  18956. +}
  18957. +
  18958. +static struct mii_bus *dev_to_mii_bus(struct device *dev)
  18959. +{
  18960. + struct device *d;
  18961. +
  18962. + d = dev_find_class(dev, "mdio_bus");
  18963. + if (d != NULL) {
  18964. + struct mii_bus *bus;
  18965. +
  18966. + bus = to_mii_bus(d);
  18967. + put_device(d);
  18968. +
  18969. + return bus;
  18970. + }
  18971. +
  18972. + return NULL;
  18973. +}
  18974. +
  18975. +int __devinit ag71xx_phy_connect(struct ag71xx *ag)
  18976. +{
  18977. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  18978. +
  18979. + ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev);
  18980. + if (ag->mii_bus == NULL) {
  18981. + printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n",
  18982. + ag->dev->name, dev_name(pdata->mii_bus_dev));
  18983. + return -ENODEV;
  18984. + }
  18985. +
  18986. + /* Reset the mdio bus explicitly */
  18987. + if (ag->mii_bus->reset) {
  18988. + mutex_lock(&ag->mii_bus->mdio_lock);
  18989. + ag->mii_bus->reset(ag->mii_bus);
  18990. + mutex_unlock(&ag->mii_bus->mdio_lock);
  18991. + }
  18992. +
  18993. + if (pdata->has_ar7240_switch)
  18994. + return ag71xx_ar7240_init(ag);
  18995. +
  18996. + if (pdata->phy_mask)
  18997. + return ag71xx_phy_connect_multi(ag);
  18998. +
  18999. + return ag71xx_phy_connect_fixed(ag);
  19000. +}
  19001. +
  19002. +void ag71xx_phy_disconnect(struct ag71xx *ag)
  19003. +{
  19004. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  19005. +
  19006. + if (pdata->has_ar7240_switch)
  19007. + ag71xx_ar7240_cleanup(ag);
  19008. + else if (ag->phy_dev)
  19009. + phy_disconnect(ag->phy_dev);
  19010. +}
  19011. diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig
  19012. --- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200
  19013. +++ linux-2.6.39/drivers/net/phy/Kconfig 2011-08-24 18:17:24.000000000 +0200
  19014. @@ -13,6 +13,12 @@
  19015. if PHYLIB
  19016. +config SWCONFIG
  19017. + tristate "Switch configuration API"
  19018. + ---help---
  19019. + Switch configuration API using netlink. This allows
  19020. + you to configure the VLAN features of certain switches.
  19021. +
  19022. comment "MII PHY device drivers"
  19023. config MARVELL_PHY
  19024. diff -Nur linux-2.6.39.orig/drivers/net/phy/Makefile linux-2.6.39/drivers/net/phy/Makefile
  19025. --- linux-2.6.39.orig/drivers/net/phy/Makefile 2011-05-19 06:06:34.000000000 +0200
  19026. +++ linux-2.6.39/drivers/net/phy/Makefile 2011-08-24 18:17:24.000000000 +0200
  19027. @@ -3,6 +3,7 @@
  19028. libphy-objs := phy.o phy_device.o mdio_bus.o
  19029. obj-$(CONFIG_PHYLIB) += libphy.o
  19030. +obj-$(CONFIG_SWCONFIG) += swconfig.o
  19031. obj-$(CONFIG_MARVELL_PHY) += marvell.o
  19032. obj-$(CONFIG_DAVICOM_PHY) += davicom.o
  19033. obj-$(CONFIG_CICADA_PHY) += cicada.o
  19034. diff -Nur linux-2.6.39.orig/drivers/net/phy/micrel.c linux-2.6.39/drivers/net/phy/micrel.c
  19035. --- linux-2.6.39.orig/drivers/net/phy/micrel.c 2011-05-19 06:06:34.000000000 +0200
  19036. +++ linux-2.6.39/drivers/net/phy/micrel.c 2011-08-24 18:17:24.000000000 +0200
  19037. @@ -1,251 +1,82 @@
  19038. /*
  19039. - * drivers/net/phy/micrel.c
  19040. + * Driver for Micrel/Kendin PHYs
  19041. *
  19042. - * Driver for Micrel PHYs
  19043. + * Copyright (c) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  19044. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  19045. *
  19046. - * Author: David J. Choi
  19047. + * This program is free software; you can redistribute it and/or modify it
  19048. + * under the terms of the GNU General Public License version 2 as published
  19049. + * by the Free Software Foundation.
  19050. *
  19051. - * Copyright (c) 2010 Micrel, Inc.
  19052. - *
  19053. - * This program is free software; you can redistribute it and/or modify it
  19054. - * under the terms of the GNU General Public License as published by the
  19055. - * Free Software Foundation; either version 2 of the License, or (at your
  19056. - * option) any later version.
  19057. - *
  19058. - * Support : ksz9021 1000/100/10 phy from Micrel
  19059. - * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy
  19060. */
  19061. -#include <linux/kernel.h>
  19062. -#include <linux/module.h>
  19063. +#include <linux/delay.h>
  19064. +#include <linux/skbuff.h>
  19065. #include <linux/phy.h>
  19066. -#include <linux/micrel_phy.h>
  19067. -/* general Interrupt control/status reg in vendor specific block. */
  19068. -#define MII_KSZPHY_INTCS 0x1B
  19069. -#define KSZPHY_INTCS_JABBER (1 << 15)
  19070. -#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14)
  19071. -#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13)
  19072. -#define KSZPHY_INTCS_PARELLEL (1 << 12)
  19073. -#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11)
  19074. -#define KSZPHY_INTCS_LINK_DOWN (1 << 10)
  19075. -#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9)
  19076. -#define KSZPHY_INTCS_LINK_UP (1 << 8)
  19077. -#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\
  19078. - KSZPHY_INTCS_LINK_DOWN)
  19079. -
  19080. -/* general PHY control reg in vendor specific block. */
  19081. -#define MII_KSZPHY_CTRL 0x1F
  19082. -/* bitmap of PHY register to set interrupt mode */
  19083. -#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9)
  19084. -#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14)
  19085. -#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14)
  19086. -#define KSZ8051_RMII_50MHZ_CLK (1 << 7)
  19087. +#define KSZ_REG_INT_CTRL 0x1b
  19088. -static int kszphy_ack_interrupt(struct phy_device *phydev)
  19089. -{
  19090. - /* bit[7..0] int status, which is a read and clear register. */
  19091. - int rc;
  19092. +#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */
  19093. +#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */
  19094. +#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */
  19095. - rc = phy_read(phydev, MII_KSZPHY_INTCS);
  19096. -
  19097. - return (rc < 0) ? rc : 0;
  19098. -}
  19099. +#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN)
  19100. -static int kszphy_set_interrupt(struct phy_device *phydev)
  19101. +static int ksz8041_ack_interrupt(struct phy_device *phydev)
  19102. {
  19103. - int temp;
  19104. - temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ?
  19105. - KSZPHY_INTCS_ALL : 0;
  19106. - return phy_write(phydev, MII_KSZPHY_INTCS, temp);
  19107. -}
  19108. + int err;
  19109. -static int kszphy_config_intr(struct phy_device *phydev)
  19110. -{
  19111. - int temp, rc;
  19112. + err = phy_read(phydev, KSZ_REG_INT_CTRL);
  19113. - /* set the interrupt pin active low */
  19114. - temp = phy_read(phydev, MII_KSZPHY_CTRL);
  19115. - temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH;
  19116. - phy_write(phydev, MII_KSZPHY_CTRL, temp);
  19117. - rc = kszphy_set_interrupt(phydev);
  19118. - return rc < 0 ? rc : 0;
  19119. + return (err < 0) ? err : 0;
  19120. }
  19121. -static int ksz9021_config_intr(struct phy_device *phydev)
  19122. +static int ksz8041_config_intr(struct phy_device *phydev)
  19123. {
  19124. - int temp, rc;
  19125. + int err;
  19126. - /* set the interrupt pin active low */
  19127. - temp = phy_read(phydev, MII_KSZPHY_CTRL);
  19128. - temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH;
  19129. - phy_write(phydev, MII_KSZPHY_CTRL, temp);
  19130. - rc = kszphy_set_interrupt(phydev);
  19131. - return rc < 0 ? rc : 0;
  19132. -}
  19133. -
  19134. -static int ks8737_config_intr(struct phy_device *phydev)
  19135. -{
  19136. - int temp, rc;
  19137. + if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  19138. + err = phy_write(phydev, KSZ_REG_INT_CTRL,
  19139. + KSZ_INT_INIT);
  19140. + else
  19141. + err = phy_write(phydev, KSZ_REG_INT_CTRL, 0);
  19142. - /* set the interrupt pin active low */
  19143. - temp = phy_read(phydev, MII_KSZPHY_CTRL);
  19144. - temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH;
  19145. - phy_write(phydev, MII_KSZPHY_CTRL, temp);
  19146. - rc = kszphy_set_interrupt(phydev);
  19147. - return rc < 0 ? rc : 0;
  19148. + return err;
  19149. }
  19150. -static int kszphy_config_init(struct phy_device *phydev)
  19151. -{
  19152. - return 0;
  19153. -}
  19154. -
  19155. -static int ks8051_config_init(struct phy_device *phydev)
  19156. -{
  19157. - int regval;
  19158. -
  19159. - if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
  19160. - regval = phy_read(phydev, MII_KSZPHY_CTRL);
  19161. - regval |= KSZ8051_RMII_50MHZ_CLK;
  19162. - phy_write(phydev, MII_KSZPHY_CTRL, regval);
  19163. - }
  19164. -
  19165. - return 0;
  19166. -}
  19167. -
  19168. -static struct phy_driver ks8737_driver = {
  19169. - .phy_id = PHY_ID_KS8737,
  19170. - .phy_id_mask = 0x00fffff0,
  19171. - .name = "Micrel KS8737",
  19172. - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
  19173. - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  19174. - .config_init = kszphy_config_init,
  19175. +static struct phy_driver ksz8041_phy_driver = {
  19176. + .phy_id = 0x00221512,
  19177. + .name = "Micrel KSZ8041",
  19178. + .phy_id_mask = 0x001fffff,
  19179. + .features = PHY_BASIC_FEATURES,
  19180. + .flags = PHY_HAS_INTERRUPT,
  19181. .config_aneg = genphy_config_aneg,
  19182. .read_status = genphy_read_status,
  19183. - .ack_interrupt = kszphy_ack_interrupt,
  19184. - .config_intr = ks8737_config_intr,
  19185. - .driver = { .owner = THIS_MODULE,},
  19186. + .ack_interrupt = ksz8041_ack_interrupt,
  19187. + .config_intr = ksz8041_config_intr,
  19188. + .driver = {
  19189. + .owner = THIS_MODULE,
  19190. + },
  19191. };
  19192. -static struct phy_driver ks8041_driver = {
  19193. - .phy_id = PHY_ID_KS8041,
  19194. - .phy_id_mask = 0x00fffff0,
  19195. - .name = "Micrel KS8041",
  19196. - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
  19197. - | SUPPORTED_Asym_Pause),
  19198. - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  19199. - .config_init = kszphy_config_init,
  19200. - .config_aneg = genphy_config_aneg,
  19201. - .read_status = genphy_read_status,
  19202. - .ack_interrupt = kszphy_ack_interrupt,
  19203. - .config_intr = kszphy_config_intr,
  19204. - .driver = { .owner = THIS_MODULE,},
  19205. -};
  19206. -
  19207. -static struct phy_driver ks8051_driver = {
  19208. - .phy_id = PHY_ID_KS8051,
  19209. - .phy_id_mask = 0x00fffff0,
  19210. - .name = "Micrel KS8051",
  19211. - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
  19212. - | SUPPORTED_Asym_Pause),
  19213. - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  19214. - .config_init = ks8051_config_init,
  19215. - .config_aneg = genphy_config_aneg,
  19216. - .read_status = genphy_read_status,
  19217. - .ack_interrupt = kszphy_ack_interrupt,
  19218. - .config_intr = kszphy_config_intr,
  19219. - .driver = { .owner = THIS_MODULE,},
  19220. -};
  19221. -
  19222. -static struct phy_driver ks8001_driver = {
  19223. - .phy_id = PHY_ID_KS8001,
  19224. - .name = "Micrel KS8001 or KS8721",
  19225. - .phy_id_mask = 0x00fffff0,
  19226. - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
  19227. - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  19228. - .config_init = kszphy_config_init,
  19229. - .config_aneg = genphy_config_aneg,
  19230. - .read_status = genphy_read_status,
  19231. - .ack_interrupt = kszphy_ack_interrupt,
  19232. - .config_intr = kszphy_config_intr,
  19233. - .driver = { .owner = THIS_MODULE,},
  19234. -};
  19235. -
  19236. -static struct phy_driver ksz9021_driver = {
  19237. - .phy_id = PHY_ID_KSZ9021,
  19238. - .phy_id_mask = 0x000fff10,
  19239. - .name = "Micrel KSZ9021 Gigabit PHY",
  19240. - .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause
  19241. - | SUPPORTED_Asym_Pause),
  19242. - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  19243. - .config_init = kszphy_config_init,
  19244. - .config_aneg = genphy_config_aneg,
  19245. - .read_status = genphy_read_status,
  19246. - .ack_interrupt = kszphy_ack_interrupt,
  19247. - .config_intr = ksz9021_config_intr,
  19248. - .driver = { .owner = THIS_MODULE, },
  19249. -};
  19250. -
  19251. -static int __init ksphy_init(void)
  19252. +static int __init micrel_phy_init(void)
  19253. {
  19254. - int ret;
  19255. -
  19256. - ret = phy_driver_register(&ks8001_driver);
  19257. - if (ret)
  19258. - goto err1;
  19259. -
  19260. - ret = phy_driver_register(&ksz9021_driver);
  19261. - if (ret)
  19262. - goto err2;
  19263. -
  19264. - ret = phy_driver_register(&ks8737_driver);
  19265. - if (ret)
  19266. - goto err3;
  19267. - ret = phy_driver_register(&ks8041_driver);
  19268. - if (ret)
  19269. - goto err4;
  19270. - ret = phy_driver_register(&ks8051_driver);
  19271. - if (ret)
  19272. - goto err5;
  19273. -
  19274. - return 0;
  19275. -
  19276. -err5:
  19277. - phy_driver_unregister(&ks8041_driver);
  19278. -err4:
  19279. - phy_driver_unregister(&ks8737_driver);
  19280. -err3:
  19281. - phy_driver_unregister(&ksz9021_driver);
  19282. -err2:
  19283. - phy_driver_unregister(&ks8001_driver);
  19284. -err1:
  19285. - return ret;
  19286. + return phy_driver_register(&ksz8041_phy_driver);
  19287. }
  19288. -static void __exit ksphy_exit(void)
  19289. +static void __exit micrel_phy_exit(void)
  19290. {
  19291. - phy_driver_unregister(&ks8001_driver);
  19292. - phy_driver_unregister(&ks8737_driver);
  19293. - phy_driver_unregister(&ksz9021_driver);
  19294. - phy_driver_unregister(&ks8041_driver);
  19295. - phy_driver_unregister(&ks8051_driver);
  19296. + phy_driver_unregister(&ksz8041_phy_driver);
  19297. }
  19298. -module_init(ksphy_init);
  19299. -module_exit(ksphy_exit);
  19300. -
  19301. -MODULE_DESCRIPTION("Micrel PHY driver");
  19302. -MODULE_AUTHOR("David J. Choi");
  19303. -MODULE_LICENSE("GPL");
  19304. -
  19305. -static struct mdio_device_id __maybe_unused micrel_tbl[] = {
  19306. - { PHY_ID_KSZ9021, 0x000fff10 },
  19307. - { PHY_ID_KS8001, 0x00fffff0 },
  19308. - { PHY_ID_KS8737, 0x00fffff0 },
  19309. - { PHY_ID_KS8041, 0x00fffff0 },
  19310. - { PHY_ID_KS8051, 0x00fffff0 },
  19311. - { }
  19312. -};
  19313. +#ifdef MODULE
  19314. +module_init(micrel_phy_init);
  19315. +module_exit(micrel_phy_exit);
  19316. +#else
  19317. +subsys_initcall(micrel_phy_init);
  19318. +#endif
  19319. -MODULE_DEVICE_TABLE(mdio, micrel_tbl);
  19320. +MODULE_DESCRIPTION("Micrel/Kendin PHY driver");
  19321. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  19322. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  19323. +MODULE_LICENSE("GPL v2");
  19324. diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c
  19325. --- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200
  19326. +++ linux-2.6.39/drivers/net/phy/phy.c 2011-08-24 18:17:24.000000000 +0200
  19327. @@ -297,6 +297,50 @@
  19328. }
  19329. EXPORT_SYMBOL(phy_ethtool_gset);
  19330. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  19331. +{
  19332. + u32 cmd;
  19333. + int tmp;
  19334. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  19335. + struct ethtool_value edata = { ETHTOOL_GLINK };
  19336. +
  19337. + if (get_user(cmd, (u32 *) useraddr))
  19338. + return -EFAULT;
  19339. +
  19340. + switch (cmd) {
  19341. + case ETHTOOL_GSET:
  19342. + phy_ethtool_gset(phydev, &ecmd);
  19343. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  19344. + return -EFAULT;
  19345. + return 0;
  19346. +
  19347. + case ETHTOOL_SSET:
  19348. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  19349. + return -EFAULT;
  19350. + return phy_ethtool_sset(phydev, &ecmd);
  19351. +
  19352. + case ETHTOOL_NWAY_RST:
  19353. + /* if autoneg is off, it's an error */
  19354. + tmp = phy_read(phydev, MII_BMCR);
  19355. + if (tmp & BMCR_ANENABLE) {
  19356. + tmp |= (BMCR_ANRESTART);
  19357. + phy_write(phydev, MII_BMCR, tmp);
  19358. + return 0;
  19359. + }
  19360. + return -EINVAL;
  19361. +
  19362. + case ETHTOOL_GLINK:
  19363. + edata.data = (phy_read(phydev,
  19364. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  19365. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  19366. + return -EFAULT;
  19367. + return 0;
  19368. + }
  19369. +
  19370. + return -EOPNOTSUPP;
  19371. +}
  19372. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  19373. +
  19374. /**
  19375. * phy_mii_ioctl - generic PHY MII ioctl interface
  19376. * @phydev: the phy_device struct
  19377. @@ -472,7 +516,7 @@
  19378. int idx;
  19379. idx = phy_find_setting(phydev->speed, phydev->duplex);
  19380. -
  19381. +
  19382. idx++;
  19383. idx = phy_find_valid(idx, phydev->supported);
  19384. diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c
  19385. --- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200
  19386. +++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-08-24 18:17:24.000000000 +0200
  19387. @@ -149,6 +149,18 @@
  19388. }
  19389. EXPORT_SYMBOL(phy_scan_fixups);
  19390. +static int generic_receive_skb(struct sk_buff *skb)
  19391. +{
  19392. + skb->protocol = eth_type_trans(skb, skb->dev);
  19393. + return netif_receive_skb(skb);
  19394. +}
  19395. +
  19396. +static int generic_rx(struct sk_buff *skb)
  19397. +{
  19398. + skb->protocol = eth_type_trans(skb, skb->dev);
  19399. + return netif_rx(skb);
  19400. +}
  19401. +
  19402. static struct phy_device* phy_device_create(struct mii_bus *bus,
  19403. int addr, int phy_id)
  19404. {
  19405. @@ -180,6 +192,8 @@
  19406. dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
  19407. dev->state = PHY_DOWN;
  19408. + dev->netif_receive_skb = &generic_receive_skb;
  19409. + dev->netif_rx = &generic_rx;
  19410. mutex_init(&dev->lock);
  19411. INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
  19412. diff -Nur linux-2.6.39.orig/drivers/net/phy/swconfig.c linux-2.6.39/drivers/net/phy/swconfig.c
  19413. --- linux-2.6.39.orig/drivers/net/phy/swconfig.c 1970-01-01 01:00:00.000000000 +0100
  19414. +++ linux-2.6.39/drivers/net/phy/swconfig.c 2011-08-24 18:17:24.000000000 +0200
  19415. @@ -0,0 +1,954 @@
  19416. +/*
  19417. + * swconfig.c: Switch configuration API
  19418. + *
  19419. + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
  19420. + *
  19421. + * This program is free software; you can redistribute it and/or
  19422. + * modify it under the terms of the GNU General Public License
  19423. + * as published by the Free Software Foundation; either version 2
  19424. + * of the License, or (at your option) any later version.
  19425. + *
  19426. + * This program is distributed in the hope that it will be useful,
  19427. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19428. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19429. + * GNU General Public License for more details.
  19430. + */
  19431. +
  19432. +#include <linux/types.h>
  19433. +#include <linux/module.h>
  19434. +#include <linux/init.h>
  19435. +#include <linux/list.h>
  19436. +#include <linux/if.h>
  19437. +#include <linux/if_ether.h>
  19438. +#include <linux/capability.h>
  19439. +#include <linux/skbuff.h>
  19440. +#include <linux/switch.h>
  19441. +
  19442. +//#define DEBUG 1
  19443. +#ifdef DEBUG
  19444. +#define DPRINTF(format, ...) printk("%s: " format, __func__, ##__VA_ARGS__)
  19445. +#else
  19446. +#define DPRINTF(...) do {} while(0)
  19447. +#endif
  19448. +
  19449. +#define SWCONFIG_DEVNAME "switch%d"
  19450. +
  19451. +MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
  19452. +MODULE_LICENSE("GPL");
  19453. +
  19454. +static int swdev_id = 0;
  19455. +static struct list_head swdevs;
  19456. +static DEFINE_SPINLOCK(swdevs_lock);
  19457. +struct swconfig_callback;
  19458. +
  19459. +struct swconfig_callback
  19460. +{
  19461. + struct sk_buff *msg;
  19462. + struct genlmsghdr *hdr;
  19463. + struct genl_info *info;
  19464. + int cmd;
  19465. +
  19466. + /* callback for filling in the message data */
  19467. + int (*fill)(struct swconfig_callback *cb, void *arg);
  19468. +
  19469. + /* callback for closing the message before sending it */
  19470. + int (*close)(struct swconfig_callback *cb, void *arg);
  19471. +
  19472. + struct nlattr *nest[4];
  19473. + int args[4];
  19474. +};
  19475. +
  19476. +/* defaults */
  19477. +
  19478. +static int
  19479. +swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19480. +{
  19481. + int ret;
  19482. + if (val->port_vlan >= dev->vlans)
  19483. + return -EINVAL;
  19484. +
  19485. + if (!dev->ops->get_vlan_ports)
  19486. + return -EOPNOTSUPP;
  19487. +
  19488. + ret = dev->ops->get_vlan_ports(dev, val);
  19489. + return ret;
  19490. +}
  19491. +
  19492. +static int
  19493. +swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19494. +{
  19495. + struct switch_port *ports = val->value.ports;
  19496. + const struct switch_dev_ops *ops = dev->ops;
  19497. + int i;
  19498. +
  19499. + if (val->port_vlan >= dev->vlans)
  19500. + return -EINVAL;
  19501. +
  19502. + /* validate ports */
  19503. + if (val->len > dev->ports)
  19504. + return -EINVAL;
  19505. +
  19506. + if (!ops->set_vlan_ports)
  19507. + return -EOPNOTSUPP;
  19508. +
  19509. + for (i = 0; i < val->len; i++) {
  19510. + if (ports[i].id >= dev->ports)
  19511. + return -EINVAL;
  19512. +
  19513. + if (ops->set_port_pvid &&
  19514. + !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
  19515. + ops->set_port_pvid(dev, ports[i].id, val->port_vlan);
  19516. + }
  19517. +
  19518. + return ops->set_vlan_ports(dev, val);
  19519. +}
  19520. +
  19521. +static int
  19522. +swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19523. +{
  19524. + if (val->port_vlan >= dev->ports)
  19525. + return -EINVAL;
  19526. +
  19527. + if (!dev->ops->set_port_pvid)
  19528. + return -EOPNOTSUPP;
  19529. +
  19530. + return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i);
  19531. +}
  19532. +
  19533. +static int
  19534. +swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19535. +{
  19536. + if (val->port_vlan >= dev->ports)
  19537. + return -EINVAL;
  19538. +
  19539. + if (!dev->ops->get_port_pvid)
  19540. + return -EOPNOTSUPP;
  19541. +
  19542. + return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i);
  19543. +}
  19544. +
  19545. +static int
  19546. +swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19547. +{
  19548. + /* don't complain if not supported by the switch driver */
  19549. + if (!dev->ops->apply_config)
  19550. + return 0;
  19551. +
  19552. + return dev->ops->apply_config(dev);
  19553. +}
  19554. +
  19555. +static int
  19556. +swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
  19557. +{
  19558. + /* don't complain if not supported by the switch driver */
  19559. + if (!dev->ops->reset_switch)
  19560. + return 0;
  19561. +
  19562. + return dev->ops->reset_switch(dev);
  19563. +}
  19564. +
  19565. +enum global_defaults {
  19566. + GLOBAL_APPLY,
  19567. + GLOBAL_RESET,
  19568. +};
  19569. +
  19570. +enum vlan_defaults {
  19571. + VLAN_PORTS,
  19572. +};
  19573. +
  19574. +enum port_defaults {
  19575. + PORT_PVID,
  19576. +};
  19577. +
  19578. +static struct switch_attr default_global[] = {
  19579. + [GLOBAL_APPLY] = {
  19580. + .type = SWITCH_TYPE_NOVAL,
  19581. + .name = "apply",
  19582. + .description = "Activate changes in the hardware",
  19583. + .set = swconfig_apply_config,
  19584. + },
  19585. + [GLOBAL_RESET] = {
  19586. + .type = SWITCH_TYPE_NOVAL,
  19587. + .name = "reset",
  19588. + .description = "Reset the switch",
  19589. + .set = swconfig_reset_switch,
  19590. + }
  19591. +};
  19592. +
  19593. +static struct switch_attr default_port[] = {
  19594. + [PORT_PVID] = {
  19595. + .type = SWITCH_TYPE_INT,
  19596. + .name = "pvid",
  19597. + .description = "Primary VLAN ID",
  19598. + .set = swconfig_set_pvid,
  19599. + .get = swconfig_get_pvid,
  19600. + }
  19601. +};
  19602. +
  19603. +static struct switch_attr default_vlan[] = {
  19604. + [VLAN_PORTS] = {
  19605. + .type = SWITCH_TYPE_PORTS,
  19606. + .name = "ports",
  19607. + .description = "VLAN port mapping",
  19608. + .set = swconfig_set_vlan_ports,
  19609. + .get = swconfig_get_vlan_ports,
  19610. + },
  19611. +};
  19612. +
  19613. +
  19614. +static void swconfig_defaults_init(struct switch_dev *dev)
  19615. +{
  19616. + const struct switch_dev_ops *ops = dev->ops;
  19617. +
  19618. + dev->def_global = 0;
  19619. + dev->def_vlan = 0;
  19620. + dev->def_port = 0;
  19621. +
  19622. + if (ops->get_vlan_ports || ops->set_vlan_ports)
  19623. + set_bit(VLAN_PORTS, &dev->def_vlan);
  19624. +
  19625. + if (ops->get_port_pvid || ops->set_port_pvid)
  19626. + set_bit(PORT_PVID, &dev->def_port);
  19627. +
  19628. + /* always present, can be no-op */
  19629. + set_bit(GLOBAL_APPLY, &dev->def_global);
  19630. + set_bit(GLOBAL_RESET, &dev->def_global);
  19631. +}
  19632. +
  19633. +
  19634. +static struct genl_family switch_fam = {
  19635. + .id = GENL_ID_GENERATE,
  19636. + .name = "switch",
  19637. + .hdrsize = 0,
  19638. + .version = 1,
  19639. + .maxattr = SWITCH_ATTR_MAX,
  19640. +};
  19641. +
  19642. +static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = {
  19643. + [SWITCH_ATTR_ID] = { .type = NLA_U32 },
  19644. + [SWITCH_ATTR_OP_ID] = { .type = NLA_U32 },
  19645. + [SWITCH_ATTR_OP_PORT] = { .type = NLA_U32 },
  19646. + [SWITCH_ATTR_OP_VLAN] = { .type = NLA_U32 },
  19647. + [SWITCH_ATTR_OP_VALUE_INT] = { .type = NLA_U32 },
  19648. + [SWITCH_ATTR_OP_VALUE_STR] = { .type = NLA_NUL_STRING },
  19649. + [SWITCH_ATTR_OP_VALUE_PORTS] = { .type = NLA_NESTED },
  19650. + [SWITCH_ATTR_TYPE] = { .type = NLA_U32 },
  19651. +};
  19652. +
  19653. +static const struct nla_policy port_policy[SWITCH_PORT_ATTR_MAX+1] = {
  19654. + [SWITCH_PORT_ID] = { .type = NLA_U32 },
  19655. + [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG },
  19656. +};
  19657. +
  19658. +static inline void
  19659. +swconfig_lock(void)
  19660. +{
  19661. + spin_lock(&swdevs_lock);
  19662. +}
  19663. +
  19664. +static inline void
  19665. +swconfig_unlock(void)
  19666. +{
  19667. + spin_unlock(&swdevs_lock);
  19668. +}
  19669. +
  19670. +static struct switch_dev *
  19671. +swconfig_get_dev(struct genl_info *info)
  19672. +{
  19673. + struct switch_dev *dev = NULL;
  19674. + struct switch_dev *p;
  19675. + int id;
  19676. +
  19677. + if (!info->attrs[SWITCH_ATTR_ID])
  19678. + goto done;
  19679. +
  19680. + id = nla_get_u32(info->attrs[SWITCH_ATTR_ID]);
  19681. + swconfig_lock();
  19682. + list_for_each_entry(p, &swdevs, dev_list) {
  19683. + if (id != p->id)
  19684. + continue;
  19685. +
  19686. + dev = p;
  19687. + break;
  19688. + }
  19689. + if (dev)
  19690. + spin_lock(&dev->lock);
  19691. + else
  19692. + DPRINTF("device %d not found\n", id);
  19693. + swconfig_unlock();
  19694. +done:
  19695. + return dev;
  19696. +}
  19697. +
  19698. +static inline void
  19699. +swconfig_put_dev(struct switch_dev *dev)
  19700. +{
  19701. + spin_unlock(&dev->lock);
  19702. +}
  19703. +
  19704. +static int
  19705. +swconfig_dump_attr(struct swconfig_callback *cb, void *arg)
  19706. +{
  19707. + struct switch_attr *op = arg;
  19708. + struct genl_info *info = cb->info;
  19709. + struct sk_buff *msg = cb->msg;
  19710. + int id = cb->args[0];
  19711. + void *hdr;
  19712. +
  19713. + hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam,
  19714. + NLM_F_MULTI, SWITCH_CMD_NEW_ATTR);
  19715. + if (IS_ERR(hdr))
  19716. + return -1;
  19717. +
  19718. + NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, id);
  19719. + NLA_PUT_U32(msg, SWITCH_ATTR_OP_TYPE, op->type);
  19720. + NLA_PUT_STRING(msg, SWITCH_ATTR_OP_NAME, op->name);
  19721. + if (op->description)
  19722. + NLA_PUT_STRING(msg, SWITCH_ATTR_OP_DESCRIPTION,
  19723. + op->description);
  19724. +
  19725. + return genlmsg_end(msg, hdr);
  19726. +nla_put_failure:
  19727. + genlmsg_cancel(msg, hdr);
  19728. + return -EMSGSIZE;
  19729. +}
  19730. +
  19731. +/* spread multipart messages across multiple message buffers */
  19732. +static int
  19733. +swconfig_send_multipart(struct swconfig_callback *cb, void *arg)
  19734. +{
  19735. + struct genl_info *info = cb->info;
  19736. + int restart = 0;
  19737. + int err;
  19738. +
  19739. + do {
  19740. + if (!cb->msg) {
  19741. + cb->msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  19742. + if (cb->msg == NULL)
  19743. + goto error;
  19744. + }
  19745. +
  19746. + if (!(cb->fill(cb, arg) < 0))
  19747. + break;
  19748. +
  19749. + /* fill failed, check if this was already the second attempt */
  19750. + if (restart)
  19751. + goto error;
  19752. +
  19753. + /* try again in a new message, send the current one */
  19754. + restart = 1;
  19755. + if (cb->close) {
  19756. + if (cb->close(cb, arg) < 0)
  19757. + goto error;
  19758. + }
  19759. + err = genlmsg_reply(cb->msg, info);
  19760. + cb->msg = NULL;
  19761. + if (err < 0)
  19762. + goto error;
  19763. +
  19764. + } while (restart);
  19765. +
  19766. + return 0;
  19767. +
  19768. +error:
  19769. + if (cb->msg)
  19770. + nlmsg_free(cb->msg);
  19771. + return -1;
  19772. +}
  19773. +
  19774. +static int
  19775. +swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info)
  19776. +{
  19777. + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
  19778. + const struct switch_attrlist *alist;
  19779. + struct switch_dev *dev;
  19780. + struct swconfig_callback cb;
  19781. + int err = -EINVAL;
  19782. + int i;
  19783. +
  19784. + /* defaults */
  19785. + struct switch_attr *def_list;
  19786. + unsigned long *def_active;
  19787. + int n_def;
  19788. +
  19789. + dev = swconfig_get_dev(info);
  19790. + if (!dev)
  19791. + return -EINVAL;
  19792. +
  19793. + switch(hdr->cmd) {
  19794. + case SWITCH_CMD_LIST_GLOBAL:
  19795. + alist = &dev->ops->attr_global;
  19796. + def_list = default_global;
  19797. + def_active = &dev->def_global;
  19798. + n_def = ARRAY_SIZE(default_global);
  19799. + break;
  19800. + case SWITCH_CMD_LIST_VLAN:
  19801. + alist = &dev->ops->attr_vlan;
  19802. + def_list = default_vlan;
  19803. + def_active = &dev->def_vlan;
  19804. + n_def = ARRAY_SIZE(default_vlan);
  19805. + break;
  19806. + case SWITCH_CMD_LIST_PORT:
  19807. + alist = &dev->ops->attr_port;
  19808. + def_list = default_port;
  19809. + def_active = &dev->def_port;
  19810. + n_def = ARRAY_SIZE(default_port);
  19811. + break;
  19812. + default:
  19813. + WARN_ON(1);
  19814. + goto out;
  19815. + }
  19816. +
  19817. + memset(&cb, 0, sizeof(cb));
  19818. + cb.info = info;
  19819. + cb.fill = swconfig_dump_attr;
  19820. + for (i = 0; i < alist->n_attr; i++) {
  19821. + if (alist->attr[i].disabled)
  19822. + continue;
  19823. + cb.args[0] = i;
  19824. + err = swconfig_send_multipart(&cb, (void *) &alist->attr[i]);
  19825. + if (err < 0)
  19826. + goto error;
  19827. + }
  19828. +
  19829. + /* defaults */
  19830. + for (i = 0; i < n_def; i++) {
  19831. + if (!test_bit(i, def_active))
  19832. + continue;
  19833. + cb.args[0] = SWITCH_ATTR_DEFAULTS_OFFSET + i;
  19834. + err = swconfig_send_multipart(&cb, (void *) &def_list[i]);
  19835. + if (err < 0)
  19836. + goto error;
  19837. + }
  19838. + swconfig_put_dev(dev);
  19839. +
  19840. + if (!cb.msg)
  19841. + return 0;
  19842. +
  19843. + return genlmsg_reply(cb.msg, info);
  19844. +
  19845. +error:
  19846. + if (cb.msg)
  19847. + nlmsg_free(cb.msg);
  19848. +out:
  19849. + swconfig_put_dev(dev);
  19850. + return err;
  19851. +}
  19852. +
  19853. +static const struct switch_attr *
  19854. +swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info,
  19855. + struct switch_val *val)
  19856. +{
  19857. + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
  19858. + const struct switch_attrlist *alist;
  19859. + const struct switch_attr *attr = NULL;
  19860. + int attr_id;
  19861. +
  19862. + /* defaults */
  19863. + struct switch_attr *def_list;
  19864. + unsigned long *def_active;
  19865. + int n_def;
  19866. +
  19867. + if (!info->attrs[SWITCH_ATTR_OP_ID])
  19868. + goto done;
  19869. +
  19870. + switch(hdr->cmd) {
  19871. + case SWITCH_CMD_SET_GLOBAL:
  19872. + case SWITCH_CMD_GET_GLOBAL:
  19873. + alist = &dev->ops->attr_global;
  19874. + def_list = default_global;
  19875. + def_active = &dev->def_global;
  19876. + n_def = ARRAY_SIZE(default_global);
  19877. + break;
  19878. + case SWITCH_CMD_SET_VLAN:
  19879. + case SWITCH_CMD_GET_VLAN:
  19880. + alist = &dev->ops->attr_vlan;
  19881. + def_list = default_vlan;
  19882. + def_active = &dev->def_vlan;
  19883. + n_def = ARRAY_SIZE(default_vlan);
  19884. + if (!info->attrs[SWITCH_ATTR_OP_VLAN])
  19885. + goto done;
  19886. + val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_VLAN]);
  19887. + if (val->port_vlan >= dev->vlans)
  19888. + goto done;
  19889. + break;
  19890. + case SWITCH_CMD_SET_PORT:
  19891. + case SWITCH_CMD_GET_PORT:
  19892. + alist = &dev->ops->attr_port;
  19893. + def_list = default_port;
  19894. + def_active = &dev->def_port;
  19895. + n_def = ARRAY_SIZE(default_port);
  19896. + if (!info->attrs[SWITCH_ATTR_OP_PORT])
  19897. + goto done;
  19898. + val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_PORT]);
  19899. + if (val->port_vlan >= dev->ports)
  19900. + goto done;
  19901. + break;
  19902. + default:
  19903. + WARN_ON(1);
  19904. + goto done;
  19905. + }
  19906. +
  19907. + if (!alist)
  19908. + goto done;
  19909. +
  19910. + attr_id = nla_get_u32(info->attrs[SWITCH_ATTR_OP_ID]);
  19911. + if (attr_id >= SWITCH_ATTR_DEFAULTS_OFFSET) {
  19912. + attr_id -= SWITCH_ATTR_DEFAULTS_OFFSET;
  19913. + if (attr_id >= n_def)
  19914. + goto done;
  19915. + if (!test_bit(attr_id, def_active))
  19916. + goto done;
  19917. + attr = &def_list[attr_id];
  19918. + } else {
  19919. + if (attr_id >= alist->n_attr)
  19920. + goto done;
  19921. + attr = &alist->attr[attr_id];
  19922. + }
  19923. +
  19924. + if (attr->disabled)
  19925. + attr = NULL;
  19926. +
  19927. +done:
  19928. + if (!attr)
  19929. + DPRINTF("attribute lookup failed\n");
  19930. + val->attr = attr;
  19931. + return attr;
  19932. +}
  19933. +
  19934. +static int
  19935. +swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head,
  19936. + struct switch_val *val, int max)
  19937. +{
  19938. + struct nlattr *nla;
  19939. + int rem;
  19940. +
  19941. + val->len = 0;
  19942. + nla_for_each_nested(nla, head, rem) {
  19943. + struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1];
  19944. + struct switch_port *port = &val->value.ports[val->len];
  19945. +
  19946. + if (val->len >= max)
  19947. + return -EINVAL;
  19948. +
  19949. + if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla,
  19950. + port_policy))
  19951. + return -EINVAL;
  19952. +
  19953. + if (!tb[SWITCH_PORT_ID])
  19954. + return -EINVAL;
  19955. +
  19956. + port->id = nla_get_u32(tb[SWITCH_PORT_ID]);
  19957. + if (tb[SWITCH_PORT_FLAG_TAGGED])
  19958. + port->flags |= (1 << SWITCH_PORT_FLAG_TAGGED);
  19959. + val->len++;
  19960. + }
  19961. +
  19962. + return 0;
  19963. +}
  19964. +
  19965. +static int
  19966. +swconfig_set_attr(struct sk_buff *skb, struct genl_info *info)
  19967. +{
  19968. + const struct switch_attr *attr;
  19969. + struct switch_dev *dev;
  19970. + struct switch_val val;
  19971. + int err = -EINVAL;
  19972. +
  19973. + dev = swconfig_get_dev(info);
  19974. + if (!dev)
  19975. + return -EINVAL;
  19976. +
  19977. + memset(&val, 0, sizeof(val));
  19978. + attr = swconfig_lookup_attr(dev, info, &val);
  19979. + if (!attr || !attr->set)
  19980. + goto error;
  19981. +
  19982. + val.attr = attr;
  19983. + switch(attr->type) {
  19984. + case SWITCH_TYPE_NOVAL:
  19985. + break;
  19986. + case SWITCH_TYPE_INT:
  19987. + if (!info->attrs[SWITCH_ATTR_OP_VALUE_INT])
  19988. + goto error;
  19989. + val.value.i =
  19990. + nla_get_u32(info->attrs[SWITCH_ATTR_OP_VALUE_INT]);
  19991. + break;
  19992. + case SWITCH_TYPE_STRING:
  19993. + if (!info->attrs[SWITCH_ATTR_OP_VALUE_STR])
  19994. + goto error;
  19995. + val.value.s =
  19996. + nla_data(info->attrs[SWITCH_ATTR_OP_VALUE_STR]);
  19997. + break;
  19998. + case SWITCH_TYPE_PORTS:
  19999. + val.value.ports = dev->portbuf;
  20000. + memset(dev->portbuf, 0,
  20001. + sizeof(struct switch_port) * dev->ports);
  20002. +
  20003. + /* TODO: implement multipart? */
  20004. + if (info->attrs[SWITCH_ATTR_OP_VALUE_PORTS]) {
  20005. + err = swconfig_parse_ports(skb,
  20006. + info->attrs[SWITCH_ATTR_OP_VALUE_PORTS], &val, dev->ports);
  20007. + if (err < 0)
  20008. + goto error;
  20009. + } else {
  20010. + val.len = 0;
  20011. + err = 0;
  20012. + }
  20013. + break;
  20014. + default:
  20015. + goto error;
  20016. + }
  20017. +
  20018. + err = attr->set(dev, attr, &val);
  20019. +error:
  20020. + swconfig_put_dev(dev);
  20021. + return err;
  20022. +}
  20023. +
  20024. +static int
  20025. +swconfig_close_portlist(struct swconfig_callback *cb, void *arg)
  20026. +{
  20027. + if (cb->nest[0])
  20028. + nla_nest_end(cb->msg, cb->nest[0]);
  20029. + return 0;
  20030. +}
  20031. +
  20032. +static int
  20033. +swconfig_send_port(struct swconfig_callback *cb, void *arg)
  20034. +{
  20035. + const struct switch_port *port = arg;
  20036. + struct nlattr *p = NULL;
  20037. +
  20038. + if (!cb->nest[0]) {
  20039. + cb->nest[0] = nla_nest_start(cb->msg, cb->cmd);
  20040. + if (!cb->nest[0])
  20041. + return -1;
  20042. + }
  20043. +
  20044. + p = nla_nest_start(cb->msg, SWITCH_ATTR_PORT);
  20045. + if (!p)
  20046. + goto error;
  20047. +
  20048. + NLA_PUT_U32(cb->msg, SWITCH_PORT_ID, port->id);
  20049. + if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED))
  20050. + NLA_PUT_FLAG(cb->msg, SWITCH_PORT_FLAG_TAGGED);
  20051. +
  20052. + nla_nest_end(cb->msg, p);
  20053. + return 0;
  20054. +
  20055. +nla_put_failure:
  20056. + nla_nest_cancel(cb->msg, p);
  20057. +error:
  20058. + nla_nest_cancel(cb->msg, cb->nest[0]);
  20059. + return -1;
  20060. +}
  20061. +
  20062. +static int
  20063. +swconfig_send_ports(struct sk_buff **msg, struct genl_info *info, int attr,
  20064. + const struct switch_val *val)
  20065. +{
  20066. + struct swconfig_callback cb;
  20067. + int err = 0;
  20068. + int i;
  20069. +
  20070. + if (!val->value.ports)
  20071. + return -EINVAL;
  20072. +
  20073. + memset(&cb, 0, sizeof(cb));
  20074. + cb.cmd = attr;
  20075. + cb.msg = *msg;
  20076. + cb.info = info;
  20077. + cb.fill = swconfig_send_port;
  20078. + cb.close = swconfig_close_portlist;
  20079. +
  20080. + cb.nest[0] = nla_nest_start(cb.msg, cb.cmd);
  20081. + for (i = 0; i < val->len; i++) {
  20082. + err = swconfig_send_multipart(&cb, &val->value.ports[i]);
  20083. + if (err)
  20084. + goto done;
  20085. + }
  20086. + err = val->len;
  20087. + swconfig_close_portlist(&cb, NULL);
  20088. + *msg = cb.msg;
  20089. +
  20090. +done:
  20091. + return err;
  20092. +}
  20093. +
  20094. +static int
  20095. +swconfig_get_attr(struct sk_buff *skb, struct genl_info *info)
  20096. +{
  20097. + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
  20098. + const struct switch_attr *attr;
  20099. + struct switch_dev *dev;
  20100. + struct sk_buff *msg = NULL;
  20101. + struct switch_val val;
  20102. + int err = -EINVAL;
  20103. + int cmd = hdr->cmd;
  20104. +
  20105. + dev = swconfig_get_dev(info);
  20106. + if (!dev)
  20107. + return -EINVAL;
  20108. +
  20109. + memset(&val, 0, sizeof(val));
  20110. + attr = swconfig_lookup_attr(dev, info, &val);
  20111. + if (!attr || !attr->get)
  20112. + goto error;
  20113. +
  20114. + if (attr->type == SWITCH_TYPE_PORTS) {
  20115. + val.value.ports = dev->portbuf;
  20116. + memset(dev->portbuf, 0,
  20117. + sizeof(struct switch_port) * dev->ports);
  20118. + }
  20119. +
  20120. + err = attr->get(dev, attr, &val);
  20121. + if (err)
  20122. + goto error;
  20123. +
  20124. + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  20125. + if (!msg)
  20126. + goto error;
  20127. +
  20128. + hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam,
  20129. + 0, cmd);
  20130. + if (IS_ERR(hdr))
  20131. + goto nla_put_failure;
  20132. +
  20133. + switch(attr->type) {
  20134. + case SWITCH_TYPE_INT:
  20135. + NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val.value.i);
  20136. + break;
  20137. + case SWITCH_TYPE_STRING:
  20138. + NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val.value.s);
  20139. + break;
  20140. + case SWITCH_TYPE_PORTS:
  20141. + err = swconfig_send_ports(&msg, info,
  20142. + SWITCH_ATTR_OP_VALUE_PORTS, &val);
  20143. + if (err < 0)
  20144. + goto nla_put_failure;
  20145. + break;
  20146. + default:
  20147. + DPRINTF("invalid type in attribute\n");
  20148. + err = -EINVAL;
  20149. + goto error;
  20150. + }
  20151. + err = genlmsg_end(msg, hdr);
  20152. + if (err < 0)
  20153. + goto nla_put_failure;
  20154. +
  20155. + swconfig_put_dev(dev);
  20156. + return genlmsg_reply(msg, info);
  20157. +
  20158. +nla_put_failure:
  20159. + if (msg)
  20160. + nlmsg_free(msg);
  20161. +error:
  20162. + swconfig_put_dev(dev);
  20163. + if (!err)
  20164. + err = -ENOMEM;
  20165. + return err;
  20166. +}
  20167. +
  20168. +static int
  20169. +swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags,
  20170. + const struct switch_dev *dev)
  20171. +{
  20172. + void *hdr;
  20173. +
  20174. + hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags,
  20175. + SWITCH_CMD_NEW_ATTR);
  20176. + if (IS_ERR(hdr))
  20177. + return -1;
  20178. +
  20179. + NLA_PUT_U32(msg, SWITCH_ATTR_ID, dev->id);
  20180. + NLA_PUT_STRING(msg, SWITCH_ATTR_DEV_NAME, dev->devname);
  20181. + NLA_PUT_STRING(msg, SWITCH_ATTR_ALIAS, dev->alias);
  20182. + NLA_PUT_STRING(msg, SWITCH_ATTR_NAME, dev->name);
  20183. + NLA_PUT_U32(msg, SWITCH_ATTR_VLANS, dev->vlans);
  20184. + NLA_PUT_U32(msg, SWITCH_ATTR_PORTS, dev->ports);
  20185. + NLA_PUT_U32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port);
  20186. +
  20187. + return genlmsg_end(msg, hdr);
  20188. +nla_put_failure:
  20189. + genlmsg_cancel(msg, hdr);
  20190. + return -EMSGSIZE;
  20191. +}
  20192. +
  20193. +static int swconfig_dump_switches(struct sk_buff *skb,
  20194. + struct netlink_callback *cb)
  20195. +{
  20196. + struct switch_dev *dev;
  20197. + int start = cb->args[0];
  20198. + int idx = 0;
  20199. +
  20200. + swconfig_lock();
  20201. + list_for_each_entry(dev, &swdevs, dev_list) {
  20202. + if (++idx <= start)
  20203. + continue;
  20204. + if (swconfig_send_switch(skb, NETLINK_CB(cb->skb).pid,
  20205. + cb->nlh->nlmsg_seq, NLM_F_MULTI,
  20206. + dev) < 0)
  20207. + break;
  20208. + }
  20209. + swconfig_unlock();
  20210. + cb->args[0] = idx;
  20211. +
  20212. + return skb->len;
  20213. +}
  20214. +
  20215. +static int
  20216. +swconfig_done(struct netlink_callback *cb)
  20217. +{
  20218. + return 0;
  20219. +}
  20220. +
  20221. +static struct genl_ops swconfig_ops[] = {
  20222. + {
  20223. + .cmd = SWITCH_CMD_LIST_GLOBAL,
  20224. + .doit = swconfig_list_attrs,
  20225. + .policy = switch_policy,
  20226. + },
  20227. + {
  20228. + .cmd = SWITCH_CMD_LIST_VLAN,
  20229. + .doit = swconfig_list_attrs,
  20230. + .policy = switch_policy,
  20231. + },
  20232. + {
  20233. + .cmd = SWITCH_CMD_LIST_PORT,
  20234. + .doit = swconfig_list_attrs,
  20235. + .policy = switch_policy,
  20236. + },
  20237. + {
  20238. + .cmd = SWITCH_CMD_GET_GLOBAL,
  20239. + .doit = swconfig_get_attr,
  20240. + .policy = switch_policy,
  20241. + },
  20242. + {
  20243. + .cmd = SWITCH_CMD_GET_VLAN,
  20244. + .doit = swconfig_get_attr,
  20245. + .policy = switch_policy,
  20246. + },
  20247. + {
  20248. + .cmd = SWITCH_CMD_GET_PORT,
  20249. + .doit = swconfig_get_attr,
  20250. + .policy = switch_policy,
  20251. + },
  20252. + {
  20253. + .cmd = SWITCH_CMD_SET_GLOBAL,
  20254. + .doit = swconfig_set_attr,
  20255. + .policy = switch_policy,
  20256. + },
  20257. + {
  20258. + .cmd = SWITCH_CMD_SET_VLAN,
  20259. + .doit = swconfig_set_attr,
  20260. + .policy = switch_policy,
  20261. + },
  20262. + {
  20263. + .cmd = SWITCH_CMD_SET_PORT,
  20264. + .doit = swconfig_set_attr,
  20265. + .policy = switch_policy,
  20266. + },
  20267. + {
  20268. + .cmd = SWITCH_CMD_GET_SWITCH,
  20269. + .dumpit = swconfig_dump_switches,
  20270. + .policy = switch_policy,
  20271. + .done = swconfig_done,
  20272. + }
  20273. +};
  20274. +
  20275. +int
  20276. +register_switch(struct switch_dev *dev, struct net_device *netdev)
  20277. +{
  20278. + struct switch_dev *sdev;
  20279. + const int max_switches = 8 * sizeof(unsigned long);
  20280. + unsigned long in_use = 0;
  20281. + int i;
  20282. +
  20283. + INIT_LIST_HEAD(&dev->dev_list);
  20284. + if (netdev) {
  20285. + dev->netdev = netdev;
  20286. + if (!dev->alias)
  20287. + dev->alias = netdev->name;
  20288. + }
  20289. + BUG_ON(!dev->alias);
  20290. +
  20291. + if (dev->ports > 0) {
  20292. + dev->portbuf = kzalloc(sizeof(struct switch_port) * dev->ports,
  20293. + GFP_KERNEL);
  20294. + if (!dev->portbuf)
  20295. + return -ENOMEM;
  20296. + }
  20297. + swconfig_defaults_init(dev);
  20298. + spin_lock_init(&dev->lock);
  20299. + swconfig_lock();
  20300. + dev->id = ++swdev_id;
  20301. +
  20302. + list_for_each_entry(sdev, &swdevs, dev_list) {
  20303. + if (!sscanf(sdev->devname, SWCONFIG_DEVNAME, &i))
  20304. + continue;
  20305. + if (i < 0 || i > max_switches)
  20306. + continue;
  20307. +
  20308. + set_bit(i, &in_use);
  20309. + }
  20310. + i = find_first_zero_bit(&in_use, max_switches);
  20311. +
  20312. + if (i == max_switches)
  20313. + return -ENFILE;
  20314. +
  20315. + /* fill device name */
  20316. + snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i);
  20317. +
  20318. + list_add(&dev->dev_list, &swdevs);
  20319. + swconfig_unlock();
  20320. +
  20321. + return 0;
  20322. +}
  20323. +EXPORT_SYMBOL_GPL(register_switch);
  20324. +
  20325. +void
  20326. +unregister_switch(struct switch_dev *dev)
  20327. +{
  20328. + kfree(dev->portbuf);
  20329. + spin_lock(&dev->lock);
  20330. + swconfig_lock();
  20331. + list_del(&dev->dev_list);
  20332. + swconfig_unlock();
  20333. + spin_unlock(&dev->lock);
  20334. +}
  20335. +EXPORT_SYMBOL_GPL(unregister_switch);
  20336. +
  20337. +
  20338. +static int __init
  20339. +swconfig_init(void)
  20340. +{
  20341. + int i, err;
  20342. +
  20343. + INIT_LIST_HEAD(&swdevs);
  20344. + err = genl_register_family(&switch_fam);
  20345. + if (err)
  20346. + return err;
  20347. +
  20348. + for (i = 0; i < ARRAY_SIZE(swconfig_ops); i++) {
  20349. + err = genl_register_ops(&switch_fam, &swconfig_ops[i]);
  20350. + if (err)
  20351. + goto unregister;
  20352. + }
  20353. +
  20354. + return 0;
  20355. +
  20356. +unregister:
  20357. + genl_unregister_family(&switch_fam);
  20358. + return err;
  20359. +}
  20360. +
  20361. +static void __exit
  20362. +swconfig_exit(void)
  20363. +{
  20364. + genl_unregister_family(&switch_fam);
  20365. +}
  20366. +
  20367. +module_init(swconfig_init);
  20368. +module_exit(swconfig_exit);
  20369. +
  20370. diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig
  20371. --- linux-2.6.39.orig/drivers/spi/Kconfig 2011-05-19 06:06:34.000000000 +0200
  20372. +++ linux-2.6.39/drivers/spi/Kconfig 2011-08-24 18:17:24.000000000 +0200
  20373. @@ -67,6 +67,13 @@
  20374. This enables support for the SPI controller present on the
  20375. Atheros AR71XX/AR724X/AR913X SoCs.
  20376. +config SPI_AR71XX
  20377. + tristate "Atheros AR71xx SPI Controller"
  20378. + depends on SPI_MASTER && ATHEROS_AR71XX
  20379. + select SPI_BITBANG
  20380. + help
  20381. + This is the SPI contoller driver for Atheros AR71xx.
  20382. +
  20383. config SPI_ATMEL
  20384. tristate "Atmel SPI Controller"
  20385. depends on (ARCH_AT91 || AVR32)
  20386. @@ -301,6 +308,12 @@
  20387. config SPI_PXA2XX_PCI
  20388. def_bool SPI_PXA2XX && X86_32 && PCI
  20389. +config SPI_RB4XX
  20390. + tristate "Mikrotik RB4XX SPI master"
  20391. + depends on SPI_MASTER && AR71XX_MACH_RB4XX
  20392. + help
  20393. + SPI controller driver for the Mikrotik RB4xx series boards.
  20394. +
  20395. config SPI_S3C24XX
  20396. tristate "Samsung S3C24XX series SPI"
  20397. depends on ARCH_S3C2410 && EXPERIMENTAL
  20398. @@ -457,6 +470,13 @@
  20399. sysfs interface, with each line presented as a kind of GPIO
  20400. exposing both switch control and diagnostic feedback.
  20401. +config SPI_RB4XX_CPLD
  20402. + tristate "MikroTik RB4XX CPLD driver"
  20403. + depends on AR71XX_MACH_RB4XX
  20404. + help
  20405. + SPI driver for the Xilinx CPLD chip present on the
  20406. + MikroTik RB4xx boards.
  20407. +
  20408. #
  20409. # Add new SPI protocol masters in alphabetical order above this line
  20410. #
  20411. diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile
  20412. --- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200
  20413. +++ linux-2.6.39/drivers/spi/Makefile 2011-08-24 18:17:24.000000000 +0200
  20414. @@ -10,6 +10,7 @@
  20415. # SPI master controller drivers (bus)
  20416. obj-$(CONFIG_SPI_ALTERA) += spi_altera.o
  20417. +obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
  20418. obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
  20419. obj-$(CONFIG_SPI_ATH79) += ath79_spi.o
  20420. obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
  20421. @@ -54,6 +55,7 @@
  20422. obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
  20423. obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
  20424. obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
  20425. +obj-$(CONFIG_SPI_RB4XX) += rb4xx_spi.o
  20426. # special build for s3c24xx spi driver with fiq support
  20427. spi_s3c24xx_hw-y := spi_s3c24xx.o
  20428. @@ -62,6 +64,7 @@
  20429. # ... add above this line ...
  20430. # SPI protocol drivers (device/link on bus)
  20431. +obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o
  20432. obj-$(CONFIG_SPI_SPIDEV) += spidev.o
  20433. obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o
  20434. # ... add above this line ...
  20435. diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c
  20436. --- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100
  20437. +++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-08-24 18:17:24.000000000 +0200
  20438. @@ -0,0 +1,283 @@
  20439. +/*
  20440. + * Atheros AP83 board specific SPI Controller driver
  20441. + *
  20442. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  20443. + *
  20444. + * This program is free software; you can redistribute it and/or modify
  20445. + * it under the terms of the GNU General Public License version 2 as
  20446. + * published by the Free Software Foundation.
  20447. + *
  20448. + */
  20449. +
  20450. +#include <linux/kernel.h>
  20451. +#include <linux/init.h>
  20452. +#include <linux/delay.h>
  20453. +#include <linux/spinlock.h>
  20454. +#include <linux/workqueue.h>
  20455. +#include <linux/platform_device.h>
  20456. +#include <linux/io.h>
  20457. +#include <linux/spi/spi.h>
  20458. +#include <linux/spi/spi_bitbang.h>
  20459. +#include <linux/bitops.h>
  20460. +#include <linux/gpio.h>
  20461. +
  20462. +#include <asm/mach-ar71xx/ar71xx.h>
  20463. +#include <asm/mach-ar71xx/platform.h>
  20464. +
  20465. +#define DRV_DESC "Atheros AP83 board SPI Controller driver"
  20466. +#define DRV_VERSION "0.1.0"
  20467. +#define DRV_NAME "ap83-spi"
  20468. +
  20469. +#define AP83_SPI_CLK_HIGH (1 << 23)
  20470. +#define AP83_SPI_CLK_LOW 0
  20471. +#define AP83_SPI_MOSI_HIGH (1 << 22)
  20472. +#define AP83_SPI_MOSI_LOW 0
  20473. +
  20474. +#define AP83_SPI_GPIO_CS 1
  20475. +#define AP83_SPI_GPIO_MISO 3
  20476. +
  20477. +struct ap83_spi {
  20478. + struct spi_bitbang bitbang;
  20479. + void __iomem *base;
  20480. + u32 addr;
  20481. +
  20482. + struct platform_device *pdev;
  20483. +};
  20484. +
  20485. +static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg)
  20486. +{
  20487. + return __raw_readl(sp->base + reg);
  20488. +}
  20489. +
  20490. +static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi)
  20491. +{
  20492. + return spi_master_get_devdata(spi->master);
  20493. +}
  20494. +
  20495. +static inline void setsck(struct spi_device *spi, int val)
  20496. +{
  20497. + struct ap83_spi *sp = spidev_to_sp(spi);
  20498. +
  20499. + if (val)
  20500. + sp->addr |= AP83_SPI_CLK_HIGH;
  20501. + else
  20502. + sp->addr &= ~AP83_SPI_CLK_HIGH;
  20503. +
  20504. + dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n",
  20505. + sp->addr, (val) ? "HIGH" : "LOW");
  20506. +
  20507. + ap83_spi_rr(sp, sp->addr);
  20508. +}
  20509. +
  20510. +static inline void setmosi(struct spi_device *spi, int val)
  20511. +{
  20512. + struct ap83_spi *sp = spidev_to_sp(spi);
  20513. +
  20514. + if (val)
  20515. + sp->addr |= AP83_SPI_MOSI_HIGH;
  20516. + else
  20517. + sp->addr &= ~AP83_SPI_MOSI_HIGH;
  20518. +
  20519. + dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n",
  20520. + sp->addr, (val) ? "HIGH" : "LOW");
  20521. +
  20522. + ap83_spi_rr(sp, sp->addr);
  20523. +}
  20524. +
  20525. +static inline u32 getmiso(struct spi_device *spi)
  20526. +{
  20527. + u32 ret;
  20528. +
  20529. + ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0;
  20530. + dev_dbg(&spi->dev, "get MISO: %d\n", ret);
  20531. +
  20532. + return ret;
  20533. +}
  20534. +
  20535. +static inline void do_spidelay(struct spi_device *spi, unsigned nsecs)
  20536. +{
  20537. + ndelay(nsecs);
  20538. +}
  20539. +
  20540. +static void ap83_spi_chipselect(struct spi_device *spi, int on)
  20541. +{
  20542. + struct ap83_spi *sp = spidev_to_sp(spi);
  20543. +
  20544. + dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1);
  20545. +
  20546. + if (on) {
  20547. + ar71xx_flash_acquire();
  20548. +
  20549. + sp->addr = 0;
  20550. + ap83_spi_rr(sp, sp->addr);
  20551. +
  20552. + gpio_set_value(AP83_SPI_GPIO_CS, 0);
  20553. + } else {
  20554. + gpio_set_value(AP83_SPI_GPIO_CS, 1);
  20555. + ar71xx_flash_release();
  20556. + }
  20557. +}
  20558. +
  20559. +#define spidelay(nsecs) \
  20560. + do { \
  20561. + /* Steal the spi_device pointer from our caller. \
  20562. + * The bitbang-API should probably get fixed here... */ \
  20563. + do_spidelay(spi, nsecs); \
  20564. + } while (0)
  20565. +
  20566. +#define EXPAND_BITBANG_TXRX
  20567. +#include <linux/spi/spi_bitbang.h>
  20568. +#include "spi_bitbang_txrx.h"
  20569. +
  20570. +static u32 ap83_spi_txrx_mode0(struct spi_device *spi,
  20571. + unsigned nsecs, u32 word, u8 bits)
  20572. +{
  20573. + dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits);
  20574. + return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
  20575. +}
  20576. +
  20577. +static u32 ap83_spi_txrx_mode1(struct spi_device *spi,
  20578. + unsigned nsecs, u32 word, u8 bits)
  20579. +{
  20580. + dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits);
  20581. + return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
  20582. +}
  20583. +
  20584. +static u32 ap83_spi_txrx_mode2(struct spi_device *spi,
  20585. + unsigned nsecs, u32 word, u8 bits)
  20586. +{
  20587. + dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits);
  20588. + return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
  20589. +}
  20590. +
  20591. +static u32 ap83_spi_txrx_mode3(struct spi_device *spi,
  20592. + unsigned nsecs, u32 word, u8 bits)
  20593. +{
  20594. + dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits);
  20595. + return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
  20596. +}
  20597. +
  20598. +static int ap83_spi_probe(struct platform_device *pdev)
  20599. +{
  20600. + struct spi_master *master;
  20601. + struct ap83_spi *sp;
  20602. + struct ap83_spi_platform_data *pdata;
  20603. + struct resource *r;
  20604. + int ret;
  20605. +
  20606. + ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso");
  20607. + if (ret) {
  20608. + dev_err(&pdev->dev, "gpio request failed for MISO\n");
  20609. + return ret;
  20610. + }
  20611. +
  20612. + ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs");
  20613. + if (ret) {
  20614. + dev_err(&pdev->dev, "gpio request failed for CS\n");
  20615. + goto err_free_miso;
  20616. + }
  20617. +
  20618. + ret = gpio_direction_input(AP83_SPI_GPIO_MISO);
  20619. + if (ret) {
  20620. + dev_err(&pdev->dev, "unable to set direction of MISO\n");
  20621. + goto err_free_cs;
  20622. + }
  20623. +
  20624. + ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0);
  20625. + if (ret) {
  20626. + dev_err(&pdev->dev, "unable to set direction of CS\n");
  20627. + goto err_free_cs;
  20628. + }
  20629. +
  20630. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  20631. + if (master == NULL) {
  20632. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  20633. + return -ENOMEM;
  20634. + }
  20635. +
  20636. + sp = spi_master_get_devdata(master);
  20637. + platform_set_drvdata(pdev, sp);
  20638. +
  20639. + pdata = pdev->dev.platform_data;
  20640. +
  20641. + sp->bitbang.master = spi_master_get(master);
  20642. + sp->bitbang.chipselect = ap83_spi_chipselect;
  20643. + sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0;
  20644. + sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1;
  20645. + sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2;
  20646. + sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3;
  20647. +
  20648. + sp->bitbang.master->bus_num = pdev->id;
  20649. + sp->bitbang.master->num_chipselect = 1;
  20650. +
  20651. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  20652. + if (r == NULL) {
  20653. + ret = -ENOENT;
  20654. + goto err_spi_put;
  20655. + }
  20656. +
  20657. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  20658. + if (!sp->base) {
  20659. + ret = -ENXIO;
  20660. + goto err_spi_put;
  20661. + }
  20662. +
  20663. + ret = spi_bitbang_start(&sp->bitbang);
  20664. + if (!ret)
  20665. + goto err_unmap;
  20666. +
  20667. + dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start);
  20668. +
  20669. + return 0;
  20670. +
  20671. +err_unmap:
  20672. + iounmap(sp->base);
  20673. +err_spi_put:
  20674. + platform_set_drvdata(pdev, NULL);
  20675. + spi_master_put(sp->bitbang.master);
  20676. +
  20677. +err_free_cs:
  20678. + gpio_free(AP83_SPI_GPIO_CS);
  20679. +err_free_miso:
  20680. + gpio_free(AP83_SPI_GPIO_MISO);
  20681. + return ret;
  20682. +}
  20683. +
  20684. +static int ap83_spi_remove(struct platform_device *pdev)
  20685. +{
  20686. + struct ap83_spi *sp = platform_get_drvdata(pdev);
  20687. +
  20688. + spi_bitbang_stop(&sp->bitbang);
  20689. + iounmap(sp->base);
  20690. + platform_set_drvdata(pdev, NULL);
  20691. + spi_master_put(sp->bitbang.master);
  20692. +
  20693. + return 0;
  20694. +}
  20695. +
  20696. +static struct platform_driver ap83_spi_drv = {
  20697. + .probe = ap83_spi_probe,
  20698. + .remove = ap83_spi_remove,
  20699. + .driver = {
  20700. + .name = DRV_NAME,
  20701. + .owner = THIS_MODULE,
  20702. + },
  20703. +};
  20704. +
  20705. +static int __init ap83_spi_init(void)
  20706. +{
  20707. + return platform_driver_register(&ap83_spi_drv);
  20708. +}
  20709. +module_init(ap83_spi_init);
  20710. +
  20711. +static void __exit ap83_spi_exit(void)
  20712. +{
  20713. + platform_driver_unregister(&ap83_spi_drv);
  20714. +}
  20715. +module_exit(ap83_spi_exit);
  20716. +
  20717. +MODULE_ALIAS("platform:" DRV_NAME);
  20718. +MODULE_DESCRIPTION(DRV_DESC);
  20719. +MODULE_VERSION(DRV_VERSION);
  20720. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  20721. +MODULE_LICENSE("GPL v2");
  20722. diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c
  20723. --- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  20724. +++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-08-24 18:17:24.000000000 +0200
  20725. @@ -0,0 +1,283 @@
  20726. +/*
  20727. + * Atheros AR71xx SPI Controller driver
  20728. + *
  20729. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  20730. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  20731. + *
  20732. + * This program is free software; you can redistribute it and/or modify
  20733. + * it under the terms of the GNU General Public License version 2 as
  20734. + * published by the Free Software Foundation.
  20735. + *
  20736. + */
  20737. +
  20738. +#include <linux/kernel.h>
  20739. +#include <linux/init.h>
  20740. +#include <linux/delay.h>
  20741. +#include <linux/spinlock.h>
  20742. +#include <linux/workqueue.h>
  20743. +#include <linux/platform_device.h>
  20744. +#include <linux/io.h>
  20745. +#include <linux/spi/spi.h>
  20746. +#include <linux/spi/spi_bitbang.h>
  20747. +#include <linux/bitops.h>
  20748. +
  20749. +#include <asm/mach-ar71xx/ar71xx.h>
  20750. +#include <asm/mach-ar71xx/platform.h>
  20751. +
  20752. +#define DRV_DESC "Atheros AR71xx SPI Controller driver"
  20753. +#define DRV_VERSION "0.2.4"
  20754. +#define DRV_NAME "ar71xx-spi"
  20755. +
  20756. +#undef PER_BIT_READ
  20757. +
  20758. +struct ar71xx_spi {
  20759. + struct spi_bitbang bitbang;
  20760. + u32 ioc_base;
  20761. + u32 reg_ctrl;
  20762. +
  20763. + void __iomem *base;
  20764. +
  20765. + struct platform_device *pdev;
  20766. + u32 (*get_ioc_base)(u8 chip_select, int cs_high,
  20767. + int is_on);
  20768. +};
  20769. +
  20770. +static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  20771. +{
  20772. + return __raw_readl(sp->base + reg);
  20773. +}
  20774. +
  20775. +static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  20776. +{
  20777. + __raw_writel(val, sp->base + reg);
  20778. +}
  20779. +
  20780. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  20781. +{
  20782. + return spi_master_get_devdata(spi->master);
  20783. +}
  20784. +
  20785. +static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  20786. +{
  20787. + u32 ret;
  20788. +
  20789. + if (is_on == AR71XX_SPI_CS_INACTIVE)
  20790. + ret = SPI_IOC_CS_ALL;
  20791. + else
  20792. + ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select);
  20793. +
  20794. + return ret;
  20795. +}
  20796. +
  20797. +static void ar71xx_spi_chipselect(struct spi_device *spi, int value)
  20798. +{
  20799. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  20800. + void __iomem *base = sp->base;
  20801. + u32 ioc_base;
  20802. +
  20803. + switch (value) {
  20804. + case BITBANG_CS_INACTIVE:
  20805. + ioc_base = sp->get_ioc_base(spi->chip_select,
  20806. + (spi->mode & SPI_CS_HIGH) != 0,
  20807. + AR71XX_SPI_CS_INACTIVE);
  20808. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  20809. + break;
  20810. +
  20811. + case BITBANG_CS_ACTIVE:
  20812. + ioc_base = sp->get_ioc_base(spi->chip_select,
  20813. + (spi->mode & SPI_CS_HIGH) != 0,
  20814. + AR71XX_SPI_CS_ACTIVE);
  20815. +
  20816. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  20817. + sp->ioc_base = ioc_base;
  20818. + break;
  20819. + }
  20820. +}
  20821. +
  20822. +static void ar71xx_spi_setup_regs(struct spi_device *spi)
  20823. +{
  20824. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  20825. +
  20826. + /* enable GPIO mode */
  20827. + ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  20828. +
  20829. + /* save CTRL register */
  20830. + sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL);
  20831. +
  20832. + /* TODO: setup speed? */
  20833. + ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43);
  20834. +}
  20835. +
  20836. +static void ar71xx_spi_restore_regs(struct spi_device *spi)
  20837. +{
  20838. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  20839. +
  20840. + /* restore CTRL register */
  20841. + ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  20842. + /* disable GPIO mode */
  20843. + ar71xx_spi_wr(sp, SPI_REG_FS, 0);
  20844. +}
  20845. +
  20846. +static int ar71xx_spi_setup(struct spi_device *spi)
  20847. +{
  20848. + int status;
  20849. +
  20850. + if (spi->bits_per_word > 32)
  20851. + return -EINVAL;
  20852. +
  20853. + if (!spi->controller_state)
  20854. + ar71xx_spi_setup_regs(spi);
  20855. +
  20856. + status = spi_bitbang_setup(spi);
  20857. + if (status && !spi->controller_state)
  20858. + ar71xx_spi_restore_regs(spi);
  20859. +
  20860. + return status;
  20861. +}
  20862. +
  20863. +static void ar71xx_spi_cleanup(struct spi_device *spi)
  20864. +{
  20865. + ar71xx_spi_restore_regs(spi);
  20866. + spi_bitbang_cleanup(spi);
  20867. +}
  20868. +
  20869. +static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  20870. + u32 word, u8 bits)
  20871. +{
  20872. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  20873. + void __iomem *base = sp->base;
  20874. + u32 ioc = sp->ioc_base;
  20875. + u32 ret;
  20876. +
  20877. + /* clock starts at inactive polarity */
  20878. + for (word <<= (32 - bits); likely(bits); bits--) {
  20879. + u32 out;
  20880. +
  20881. + if (word & (1 << 31))
  20882. + out = ioc | SPI_IOC_DO;
  20883. + else
  20884. + out = ioc & ~SPI_IOC_DO;
  20885. +
  20886. + /* setup MSB (to slave) on trailing edge */
  20887. + __raw_writel(out, base + SPI_REG_IOC);
  20888. +
  20889. + __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC);
  20890. +
  20891. + word <<= 1;
  20892. +
  20893. +#ifdef PER_BIT_READ
  20894. + /* sample MSB (from slave) on leading edge */
  20895. + ret = __raw_readl(base + SPI_REG_RDS);
  20896. + __raw_writel(out, base + SPI_REG_IOC);
  20897. +#endif
  20898. +
  20899. + }
  20900. +
  20901. +#ifndef PER_BIT_READ
  20902. + ret = __raw_readl(base + SPI_REG_RDS);
  20903. +#endif
  20904. + return ret;
  20905. +}
  20906. +
  20907. +static int ar71xx_spi_probe(struct platform_device *pdev)
  20908. +{
  20909. + struct spi_master *master;
  20910. + struct ar71xx_spi *sp;
  20911. + struct ar71xx_spi_platform_data *pdata;
  20912. + struct resource *r;
  20913. + int ret;
  20914. +
  20915. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  20916. + if (master == NULL) {
  20917. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  20918. + return -ENOMEM;
  20919. + }
  20920. +
  20921. + sp = spi_master_get_devdata(master);
  20922. + platform_set_drvdata(pdev, sp);
  20923. +
  20924. + pdata = pdev->dev.platform_data;
  20925. +
  20926. + master->setup = ar71xx_spi_setup;
  20927. + master->cleanup = ar71xx_spi_cleanup;
  20928. +
  20929. + sp->bitbang.master = spi_master_get(master);
  20930. + sp->bitbang.chipselect = ar71xx_spi_chipselect;
  20931. + sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
  20932. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  20933. +
  20934. + sp->get_ioc_base = ar71xx_spi_get_ioc_base;
  20935. + if (pdata) {
  20936. + sp->bitbang.master->bus_num = pdata->bus_num;
  20937. + sp->bitbang.master->num_chipselect = pdata->num_chipselect;
  20938. + if (pdata->get_ioc_base)
  20939. + sp->get_ioc_base = pdata->get_ioc_base;
  20940. + } else {
  20941. + sp->bitbang.master->bus_num = 0;
  20942. + sp->bitbang.master->num_chipselect = 3;
  20943. + }
  20944. +
  20945. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  20946. + if (r == NULL) {
  20947. + ret = -ENOENT;
  20948. + goto err1;
  20949. + }
  20950. +
  20951. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  20952. + if (!sp->base) {
  20953. + ret = -ENXIO;
  20954. + goto err1;
  20955. + }
  20956. +
  20957. + ret = spi_bitbang_start(&sp->bitbang);
  20958. + if (!ret)
  20959. + return 0;
  20960. +
  20961. + iounmap(sp->base);
  20962. +err1:
  20963. + platform_set_drvdata(pdev, NULL);
  20964. + spi_master_put(sp->bitbang.master);
  20965. +
  20966. + return ret;
  20967. +}
  20968. +
  20969. +static int ar71xx_spi_remove(struct platform_device *pdev)
  20970. +{
  20971. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  20972. +
  20973. + spi_bitbang_stop(&sp->bitbang);
  20974. + iounmap(sp->base);
  20975. + platform_set_drvdata(pdev, NULL);
  20976. + spi_master_put(sp->bitbang.master);
  20977. +
  20978. + return 0;
  20979. +}
  20980. +
  20981. +static struct platform_driver ar71xx_spi_drv = {
  20982. + .probe = ar71xx_spi_probe,
  20983. + .remove = ar71xx_spi_remove,
  20984. + .driver = {
  20985. + .name = DRV_NAME,
  20986. + .owner = THIS_MODULE,
  20987. + },
  20988. +};
  20989. +
  20990. +static int __init ar71xx_spi_init(void)
  20991. +{
  20992. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  20993. + return platform_driver_register(&ar71xx_spi_drv);
  20994. +}
  20995. +module_init(ar71xx_spi_init);
  20996. +
  20997. +static void __exit ar71xx_spi_exit(void)
  20998. +{
  20999. + platform_driver_unregister(&ar71xx_spi_drv);
  21000. +}
  21001. +module_exit(ar71xx_spi_exit);
  21002. +
  21003. +MODULE_ALIAS("platform:" DRV_NAME);
  21004. +MODULE_DESCRIPTION(DRV_DESC);
  21005. +MODULE_VERSION(DRV_VERSION);
  21006. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  21007. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  21008. +MODULE_LICENSE("GPL v2");
  21009. diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44_spi.c
  21010. --- linux-2.6.39.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100
  21011. +++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-08-24 18:17:24.000000000 +0200
  21012. @@ -0,0 +1,299 @@
  21013. +/*
  21014. + * Atheros PB44 board SPI controller driver
  21015. + *
  21016. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  21017. + *
  21018. + * This program is free software; you can redistribute it and/or modify
  21019. + * it under the terms of the GNU General Public License version 2 as
  21020. + * published by the Free Software Foundation.
  21021. + *
  21022. + */
  21023. +
  21024. +#include <linux/kernel.h>
  21025. +#include <linux/init.h>
  21026. +#include <linux/delay.h>
  21027. +#include <linux/spinlock.h>
  21028. +#include <linux/workqueue.h>
  21029. +#include <linux/platform_device.h>
  21030. +#include <linux/io.h>
  21031. +#include <linux/spi/spi.h>
  21032. +#include <linux/spi/spi_bitbang.h>
  21033. +#include <linux/bitops.h>
  21034. +#include <linux/gpio.h>
  21035. +
  21036. +#include <asm/mach-ar71xx/ar71xx.h>
  21037. +#include <asm/mach-ar71xx/platform.h>
  21038. +
  21039. +#define DRV_DESC "Atheros PB44 SPI Controller driver"
  21040. +#define DRV_VERSION "0.1.0"
  21041. +#define DRV_NAME "pb44-spi"
  21042. +
  21043. +#undef PER_BIT_READ
  21044. +
  21045. +struct ar71xx_spi {
  21046. + struct spi_bitbang bitbang;
  21047. + u32 ioc_base;
  21048. + u32 reg_ctrl;
  21049. +
  21050. + void __iomem *base;
  21051. +
  21052. + struct platform_device *pdev;
  21053. +};
  21054. +
  21055. +static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  21056. +{
  21057. + return __raw_readl(sp->base + reg);
  21058. +}
  21059. +
  21060. +static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  21061. +{
  21062. + __raw_writel(val, sp->base + reg);
  21063. +}
  21064. +
  21065. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  21066. +{
  21067. + return spi_master_get_devdata(spi->master);
  21068. +}
  21069. +
  21070. +static void pb44_spi_chipselect(struct spi_device *spi, int is_active)
  21071. +{
  21072. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  21073. + int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
  21074. +
  21075. + if (is_active) {
  21076. + /* set initial clock polarity */
  21077. + if (spi->mode & SPI_CPOL)
  21078. + sp->ioc_base |= SPI_IOC_CLK;
  21079. + else
  21080. + sp->ioc_base &= ~SPI_IOC_CLK;
  21081. +
  21082. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  21083. + }
  21084. +
  21085. + if (spi->chip_select) {
  21086. + unsigned long gpio = (unsigned long) spi->controller_data;
  21087. +
  21088. + /* SPI is normally active-low */
  21089. + gpio_set_value(gpio, cs_high);
  21090. + } else {
  21091. + if (cs_high)
  21092. + sp->ioc_base |= SPI_IOC_CS0;
  21093. + else
  21094. + sp->ioc_base &= ~SPI_IOC_CS0;
  21095. +
  21096. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  21097. + }
  21098. +
  21099. +}
  21100. +
  21101. +static int pb44_spi_setup_cs(struct spi_device *spi)
  21102. +{
  21103. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  21104. +
  21105. + /* enable GPIO mode */
  21106. + pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  21107. +
  21108. + /* save CTRL register */
  21109. + sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL);
  21110. + sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC);
  21111. +
  21112. + /* TODO: setup speed? */
  21113. + pb44_spi_wr(sp, SPI_REG_CTRL, 0x43);
  21114. +
  21115. + if (spi->chip_select) {
  21116. + unsigned long gpio = (unsigned long) spi->controller_data;
  21117. + int status = 0;
  21118. +
  21119. + status = gpio_request(gpio, dev_name(&spi->dev));
  21120. + if (status)
  21121. + return status;
  21122. +
  21123. + status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
  21124. + if (status) {
  21125. + gpio_free(gpio);
  21126. + return status;
  21127. + }
  21128. + } else {
  21129. + if (spi->mode & SPI_CS_HIGH)
  21130. + sp->ioc_base |= SPI_IOC_CS0;
  21131. + else
  21132. + sp->ioc_base &= ~SPI_IOC_CS0;
  21133. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  21134. + }
  21135. +
  21136. + return 0;
  21137. +}
  21138. +
  21139. +static void pb44_spi_cleanup_cs(struct spi_device *spi)
  21140. +{
  21141. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  21142. +
  21143. + if (spi->chip_select) {
  21144. + unsigned long gpio = (unsigned long) spi->controller_data;
  21145. + gpio_free(gpio);
  21146. + }
  21147. +
  21148. + /* restore CTRL register */
  21149. + pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  21150. + /* disable GPIO mode */
  21151. + pb44_spi_wr(sp, SPI_REG_FS, 0);
  21152. +}
  21153. +
  21154. +static int pb44_spi_setup(struct spi_device *spi)
  21155. +{
  21156. + int status = 0;
  21157. +
  21158. + if (spi->bits_per_word > 32)
  21159. + return -EINVAL;
  21160. +
  21161. + if (!spi->controller_state) {
  21162. + status = pb44_spi_setup_cs(spi);
  21163. + if (status)
  21164. + return status;
  21165. + }
  21166. +
  21167. + status = spi_bitbang_setup(spi);
  21168. + if (status && !spi->controller_state)
  21169. + pb44_spi_cleanup_cs(spi);
  21170. +
  21171. + return status;
  21172. +}
  21173. +
  21174. +static void pb44_spi_cleanup(struct spi_device *spi)
  21175. +{
  21176. + pb44_spi_cleanup_cs(spi);
  21177. + spi_bitbang_cleanup(spi);
  21178. +}
  21179. +
  21180. +static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  21181. + u32 word, u8 bits)
  21182. +{
  21183. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  21184. + u32 ioc = sp->ioc_base;
  21185. + u32 ret;
  21186. +
  21187. + /* clock starts at inactive polarity */
  21188. + for (word <<= (32 - bits); likely(bits); bits--) {
  21189. + u32 out;
  21190. +
  21191. + if (word & (1 << 31))
  21192. + out = ioc | SPI_IOC_DO;
  21193. + else
  21194. + out = ioc & ~SPI_IOC_DO;
  21195. +
  21196. + /* setup MSB (to slave) on trailing edge */
  21197. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  21198. + pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK);
  21199. +
  21200. + word <<= 1;
  21201. +
  21202. +#ifdef PER_BIT_READ
  21203. + /* sample MSB (from slave) on leading edge */
  21204. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  21205. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  21206. +#endif
  21207. + }
  21208. +
  21209. +#ifndef PER_BIT_READ
  21210. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  21211. +#endif
  21212. + return ret;
  21213. +}
  21214. +
  21215. +static int pb44_spi_probe(struct platform_device *pdev)
  21216. +{
  21217. + struct spi_master *master;
  21218. + struct ar71xx_spi *sp;
  21219. + struct ar71xx_spi_platform_data *pdata;
  21220. + struct resource *r;
  21221. + int ret;
  21222. +
  21223. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  21224. + if (master == NULL) {
  21225. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  21226. + return -ENOMEM;
  21227. + }
  21228. +
  21229. + sp = spi_master_get_devdata(master);
  21230. + platform_set_drvdata(pdev, sp);
  21231. +
  21232. + pdata = pdev->dev.platform_data;
  21233. +
  21234. + master->setup = pb44_spi_setup;
  21235. + master->cleanup = pb44_spi_cleanup;
  21236. + if (pdata) {
  21237. + master->bus_num = pdata->bus_num;
  21238. + master->num_chipselect = pdata->num_chipselect;
  21239. + } else {
  21240. + master->bus_num = 0;
  21241. + master->num_chipselect = 1;
  21242. + }
  21243. +
  21244. + sp->bitbang.master = spi_master_get(master);
  21245. + sp->bitbang.chipselect = pb44_spi_chipselect;
  21246. + sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0;
  21247. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  21248. + sp->bitbang.flags = SPI_CS_HIGH;
  21249. +
  21250. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  21251. + if (r == NULL) {
  21252. + ret = -ENOENT;
  21253. + goto err1;
  21254. + }
  21255. +
  21256. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  21257. + if (!sp->base) {
  21258. + ret = -ENXIO;
  21259. + goto err1;
  21260. + }
  21261. +
  21262. + ret = spi_bitbang_start(&sp->bitbang);
  21263. + if (!ret)
  21264. + return 0;
  21265. +
  21266. + iounmap(sp->base);
  21267. +err1:
  21268. + platform_set_drvdata(pdev, NULL);
  21269. + spi_master_put(sp->bitbang.master);
  21270. +
  21271. + return ret;
  21272. +}
  21273. +
  21274. +static int pb44_spi_remove(struct platform_device *pdev)
  21275. +{
  21276. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  21277. +
  21278. + spi_bitbang_stop(&sp->bitbang);
  21279. + iounmap(sp->base);
  21280. + platform_set_drvdata(pdev, NULL);
  21281. + spi_master_put(sp->bitbang.master);
  21282. +
  21283. + return 0;
  21284. +}
  21285. +
  21286. +static struct platform_driver pb44_spi_drv = {
  21287. + .probe = pb44_spi_probe,
  21288. + .remove = pb44_spi_remove,
  21289. + .driver = {
  21290. + .name = DRV_NAME,
  21291. + .owner = THIS_MODULE,
  21292. + },
  21293. +};
  21294. +
  21295. +static int __init pb44_spi_init(void)
  21296. +{
  21297. + return platform_driver_register(&pb44_spi_drv);
  21298. +}
  21299. +module_init(pb44_spi_init);
  21300. +
  21301. +static void __exit pb44_spi_exit(void)
  21302. +{
  21303. + platform_driver_unregister(&pb44_spi_drv);
  21304. +}
  21305. +module_exit(pb44_spi_exit);
  21306. +
  21307. +MODULE_ALIAS("platform:" DRV_NAME);
  21308. +MODULE_DESCRIPTION(DRV_DESC);
  21309. +MODULE_VERSION(DRV_VERSION);
  21310. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  21311. +MODULE_LICENSE("GPL v2");
  21312. diff -Nur linux-2.6.39.orig/drivers/spi/rb4xx_spi.c linux-2.6.39/drivers/spi/rb4xx_spi.c
  21313. --- linux-2.6.39.orig/drivers/spi/rb4xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  21314. +++ linux-2.6.39/drivers/spi/rb4xx_spi.c 2011-08-24 18:17:24.000000000 +0200
  21315. @@ -0,0 +1,474 @@
  21316. +/*
  21317. + * SPI controller driver for the Mikrotik RB4xx boards
  21318. + *
  21319. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  21320. + *
  21321. + * This file was based on the patches for Linux 2.6.27.39 published by
  21322. + * MikroTik for their RouterBoard 4xx series devices.
  21323. + *
  21324. + * This program is free software; you can redistribute it and/or modify
  21325. + * it under the terms of the GNU General Public License version 2 as
  21326. + * published by the Free Software Foundation.
  21327. + *
  21328. + */
  21329. +
  21330. +#include <linux/kernel.h>
  21331. +#include <linux/init.h>
  21332. +#include <linux/delay.h>
  21333. +#include <linux/spinlock.h>
  21334. +#include <linux/workqueue.h>
  21335. +#include <linux/platform_device.h>
  21336. +#include <linux/spi/spi.h>
  21337. +
  21338. +#include <asm/mach-ar71xx/ar71xx.h>
  21339. +
  21340. +#define DRV_NAME "rb4xx-spi"
  21341. +#define DRV_DESC "Mikrotik RB4xx SPI controller driver"
  21342. +#define DRV_VERSION "0.1.0"
  21343. +
  21344. +#define SPI_CTRL_FASTEST 0x40
  21345. +#define SPI_FLASH_HZ 33333334
  21346. +#define SPI_CPLD_HZ 33333334
  21347. +
  21348. +#define CPLD_CMD_READ_FAST 0x0b
  21349. +
  21350. +#undef RB4XX_SPI_DEBUG
  21351. +
  21352. +struct rb4xx_spi {
  21353. + void __iomem *base;
  21354. + struct spi_master *master;
  21355. +
  21356. + unsigned spi_ctrl_flash;
  21357. + unsigned spi_ctrl_fread;
  21358. +
  21359. + spinlock_t lock;
  21360. + struct list_head queue;
  21361. + int busy:1;
  21362. + int cs_wait;
  21363. +};
  21364. +
  21365. +static unsigned spi_clk_low = SPI_IOC_CS1;
  21366. +
  21367. +#ifdef RB4XX_SPI_DEBUG
  21368. +static inline void do_spi_delay(void)
  21369. +{
  21370. + ndelay(20000);
  21371. +}
  21372. +#else
  21373. +static inline void do_spi_delay(void) { }
  21374. +#endif
  21375. +
  21376. +static inline void do_spi_init(struct spi_device *spi)
  21377. +{
  21378. + unsigned cs = SPI_IOC_CS0 | SPI_IOC_CS1;
  21379. +
  21380. + if (!(spi->mode & SPI_CS_HIGH))
  21381. + cs ^= (spi->chip_select == 2) ? SPI_IOC_CS1 : SPI_IOC_CS0;
  21382. +
  21383. + spi_clk_low = cs;
  21384. +}
  21385. +
  21386. +static inline void do_spi_finish(void __iomem *base)
  21387. +{
  21388. + do_spi_delay();
  21389. + __raw_writel(SPI_IOC_CS0 | SPI_IOC_CS1, base + SPI_REG_IOC);
  21390. +}
  21391. +
  21392. +static inline void do_spi_clk(void __iomem *base, int bit)
  21393. +{
  21394. + unsigned bval = spi_clk_low | ((bit & 1) ? SPI_IOC_DO : 0);
  21395. +
  21396. + do_spi_delay();
  21397. + __raw_writel(bval, base + SPI_REG_IOC);
  21398. + do_spi_delay();
  21399. + __raw_writel(bval | SPI_IOC_CLK, base + SPI_REG_IOC);
  21400. +}
  21401. +
  21402. +static void do_spi_byte(void __iomem *base, unsigned char byte)
  21403. +{
  21404. + do_spi_clk(base, byte >> 7);
  21405. + do_spi_clk(base, byte >> 6);
  21406. + do_spi_clk(base, byte >> 5);
  21407. + do_spi_clk(base, byte >> 4);
  21408. + do_spi_clk(base, byte >> 3);
  21409. + do_spi_clk(base, byte >> 2);
  21410. + do_spi_clk(base, byte >> 1);
  21411. + do_spi_clk(base, byte);
  21412. +
  21413. + pr_debug("spi_byte sent 0x%02x got 0x%02x\n",
  21414. + (unsigned)byte,
  21415. + (unsigned char)__raw_readl(base + SPI_REG_RDS));
  21416. +}
  21417. +
  21418. +static inline void do_spi_clk_fast(void __iomem *base, unsigned bit1,
  21419. + unsigned bit2)
  21420. +{
  21421. + unsigned bval = (spi_clk_low |
  21422. + ((bit1 & 1) ? SPI_IOC_DO : 0) |
  21423. + ((bit2 & 1) ? SPI_IOC_CS2 : 0));
  21424. + do_spi_delay();
  21425. + __raw_writel(bval, base + SPI_REG_IOC);
  21426. + do_spi_delay();
  21427. + __raw_writel(bval | SPI_IOC_CLK, base + SPI_REG_IOC);
  21428. +}
  21429. +
  21430. +static void do_spi_byte_fast(void __iomem *base, unsigned char byte)
  21431. +{
  21432. + do_spi_clk_fast(base, byte >> 7, byte >> 6);
  21433. + do_spi_clk_fast(base, byte >> 5, byte >> 4);
  21434. + do_spi_clk_fast(base, byte >> 3, byte >> 2);
  21435. + do_spi_clk_fast(base, byte >> 1, byte >> 0);
  21436. +
  21437. + pr_debug("spi_byte_fast sent 0x%02x got 0x%02x\n",
  21438. + (unsigned)byte,
  21439. + (unsigned char) __raw_readl(base + SPI_REG_RDS));
  21440. +}
  21441. +
  21442. +static int rb4xx_spi_txrx(void __iomem *base, struct spi_transfer *t)
  21443. +{
  21444. + const unsigned char *rxv_ptr = NULL;
  21445. + const unsigned char *tx_ptr = t->tx_buf;
  21446. + unsigned char *rx_ptr = t->rx_buf;
  21447. + unsigned i;
  21448. +
  21449. + pr_debug("spi_txrx len %u tx %u rx %u\n",
  21450. + t->len,
  21451. + (t->tx_buf ? 1 : 0),
  21452. + (t->rx_buf ? 1 : 0));
  21453. +
  21454. + if (t->verify) {
  21455. + rxv_ptr = tx_ptr;
  21456. + tx_ptr = NULL;
  21457. + }
  21458. +
  21459. + for (i = 0; i < t->len; ++i) {
  21460. + unsigned char sdata = tx_ptr ? tx_ptr[i] : 0;
  21461. +
  21462. + if (t->fast_write)
  21463. + do_spi_byte_fast(base, sdata);
  21464. + else
  21465. + do_spi_byte(base, sdata);
  21466. +
  21467. + if (rx_ptr) {
  21468. + rx_ptr[i] = __raw_readl(base + SPI_REG_RDS) & 0xff;
  21469. + } else if (rxv_ptr) {
  21470. + unsigned char c = __raw_readl(base + SPI_REG_RDS);
  21471. + if (rxv_ptr[i] != c)
  21472. + return i;
  21473. + }
  21474. + }
  21475. +
  21476. + return i;
  21477. +}
  21478. +
  21479. +static int rb4xx_spi_read_fast(struct rb4xx_spi *rbspi,
  21480. + struct spi_message *m)
  21481. +{
  21482. + struct spi_transfer *t;
  21483. + const unsigned char *tx_ptr;
  21484. + unsigned addr;
  21485. + void __iomem *base = rbspi->base;
  21486. +
  21487. + /* check for exactly two transfers */
  21488. + if (list_empty(&m->transfers) ||
  21489. + list_is_last(m->transfers.next, &m->transfers) ||
  21490. + !list_is_last(m->transfers.next->next, &m->transfers)) {
  21491. + return -1;
  21492. + }
  21493. +
  21494. + /* first transfer contains command and address */
  21495. + t = list_entry(m->transfers.next,
  21496. + struct spi_transfer, transfer_list);
  21497. +
  21498. + if (t->len != 5 || t->tx_buf == NULL)
  21499. + return -1;
  21500. +
  21501. + tx_ptr = t->tx_buf;
  21502. + if (tx_ptr[0] != CPLD_CMD_READ_FAST)
  21503. + return -1;
  21504. +
  21505. + addr = tx_ptr[1];
  21506. + addr = tx_ptr[2] | (addr << 8);
  21507. + addr = tx_ptr[3] | (addr << 8);
  21508. + addr += (unsigned) base;
  21509. +
  21510. + m->actual_length += t->len;
  21511. +
  21512. + /* second transfer contains data itself */
  21513. + t = list_entry(m->transfers.next->next,
  21514. + struct spi_transfer, transfer_list);
  21515. +
  21516. + if (t->tx_buf && !t->verify)
  21517. + return -1;
  21518. +
  21519. + __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS);
  21520. + __raw_writel(rbspi->spi_ctrl_fread, base + SPI_REG_CTRL);
  21521. + __raw_writel(0, base + SPI_REG_FS);
  21522. +
  21523. + if (t->rx_buf) {
  21524. + memcpy(t->rx_buf, (const void *)addr, t->len);
  21525. + } else if (t->tx_buf) {
  21526. + unsigned char buf[t->len];
  21527. + memcpy(buf, (const void *)addr, t->len);
  21528. + if (memcmp(t->tx_buf, buf, t->len) != 0)
  21529. + m->status = -EMSGSIZE;
  21530. + }
  21531. + m->actual_length += t->len;
  21532. +
  21533. + if (rbspi->spi_ctrl_flash != rbspi->spi_ctrl_fread) {
  21534. + __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS);
  21535. + __raw_writel(rbspi->spi_ctrl_flash, base + SPI_REG_CTRL);
  21536. + __raw_writel(0, base + SPI_REG_FS);
  21537. + }
  21538. +
  21539. + return 0;
  21540. +}
  21541. +
  21542. +static int rb4xx_spi_msg(struct rb4xx_spi *rbspi, struct spi_message *m)
  21543. +{
  21544. + struct spi_transfer *t = NULL;
  21545. + void __iomem *base = rbspi->base;
  21546. +
  21547. + m->status = 0;
  21548. + if (list_empty(&m->transfers))
  21549. + return -1;
  21550. +
  21551. + if (m->fast_read)
  21552. + if (rb4xx_spi_read_fast(rbspi, m) == 0)
  21553. + return -1;
  21554. +
  21555. + __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS);
  21556. + __raw_writel(SPI_CTRL_FASTEST, base + SPI_REG_CTRL);
  21557. + do_spi_init(m->spi);
  21558. +
  21559. + list_for_each_entry(t, &m->transfers, transfer_list) {
  21560. + int len;
  21561. +
  21562. + len = rb4xx_spi_txrx(base, t);
  21563. + if (len != t->len) {
  21564. + m->status = -EMSGSIZE;
  21565. + break;
  21566. + }
  21567. + m->actual_length += len;
  21568. +
  21569. + if (t->cs_change) {
  21570. + if (list_is_last(&t->transfer_list, &m->transfers)) {
  21571. + /* wait for continuation */
  21572. + return m->spi->chip_select;
  21573. + }
  21574. + do_spi_finish(base);
  21575. + ndelay(100);
  21576. + }
  21577. + }
  21578. +
  21579. + do_spi_finish(base);
  21580. + __raw_writel(rbspi->spi_ctrl_flash, base + SPI_REG_CTRL);
  21581. + __raw_writel(0, base + SPI_REG_FS);
  21582. + return -1;
  21583. +}
  21584. +
  21585. +static void rb4xx_spi_process_queue_locked(struct rb4xx_spi *rbspi,
  21586. + unsigned long *flags)
  21587. +{
  21588. + int cs = rbspi->cs_wait;
  21589. +
  21590. + rbspi->busy = 1;
  21591. + while (!list_empty(&rbspi->queue)) {
  21592. + struct spi_message *m;
  21593. +
  21594. + list_for_each_entry(m, &rbspi->queue, queue)
  21595. + if (cs < 0 || cs == m->spi->chip_select)
  21596. + break;
  21597. +
  21598. + if (&m->queue == &rbspi->queue)
  21599. + break;
  21600. +
  21601. + list_del_init(&m->queue);
  21602. + spin_unlock_irqrestore(&rbspi->lock, *flags);
  21603. +
  21604. + cs = rb4xx_spi_msg(rbspi, m);
  21605. + m->complete(m->context);
  21606. +
  21607. + spin_lock_irqsave(&rbspi->lock, *flags);
  21608. + }
  21609. +
  21610. + rbspi->cs_wait = cs;
  21611. + rbspi->busy = 0;
  21612. +
  21613. + if (cs >= 0) {
  21614. + /* TODO: add timer to unlock cs after 1s inactivity */
  21615. + }
  21616. +}
  21617. +
  21618. +static int rb4xx_spi_transfer(struct spi_device *spi,
  21619. + struct spi_message *m)
  21620. +{
  21621. + struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master);
  21622. + unsigned long flags;
  21623. +
  21624. + m->actual_length = 0;
  21625. + m->status = -EINPROGRESS;
  21626. +
  21627. + spin_lock_irqsave(&rbspi->lock, flags);
  21628. + list_add_tail(&m->queue, &rbspi->queue);
  21629. + if (rbspi->busy ||
  21630. + (rbspi->cs_wait >= 0 && rbspi->cs_wait != m->spi->chip_select)) {
  21631. + /* job will be done later */
  21632. + spin_unlock_irqrestore(&rbspi->lock, flags);
  21633. + return 0;
  21634. + }
  21635. +
  21636. + /* process job in current context */
  21637. + rb4xx_spi_process_queue_locked(rbspi, &flags);
  21638. + spin_unlock_irqrestore(&rbspi->lock, flags);
  21639. +
  21640. + return 0;
  21641. +}
  21642. +
  21643. +static int rb4xx_spi_setup(struct spi_device *spi)
  21644. +{
  21645. + struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master);
  21646. + unsigned long flags;
  21647. +
  21648. + if (spi->mode & ~(SPI_CS_HIGH)) {
  21649. + dev_err(&spi->dev, "mode %x not supported\n",
  21650. + (unsigned) spi->mode);
  21651. + return -EINVAL;
  21652. + }
  21653. +
  21654. + if (spi->bits_per_word != 8 && spi->bits_per_word != 0) {
  21655. + dev_err(&spi->dev, "bits_per_word %u not supported\n",
  21656. + (unsigned) spi->bits_per_word);
  21657. + return -EINVAL;
  21658. + }
  21659. +
  21660. + spin_lock_irqsave(&rbspi->lock, flags);
  21661. + if (rbspi->cs_wait == spi->chip_select && !rbspi->busy) {
  21662. + rbspi->cs_wait = -1;
  21663. + rb4xx_spi_process_queue_locked(rbspi, &flags);
  21664. + }
  21665. + spin_unlock_irqrestore(&rbspi->lock, flags);
  21666. +
  21667. + return 0;
  21668. +}
  21669. +
  21670. +static unsigned get_spi_ctrl(unsigned hz_max, const char *name)
  21671. +{
  21672. + unsigned div;
  21673. +
  21674. + div = (ar71xx_ahb_freq - 1) / (2 * hz_max);
  21675. +
  21676. + /*
  21677. + * CPU has a bug at (div == 0) - first bit read is random
  21678. + */
  21679. + if (div == 0)
  21680. + ++div;
  21681. +
  21682. + if (name) {
  21683. + unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000;
  21684. + unsigned div_real = 2 * (div + 1);
  21685. + pr_debug("rb4xx: %s SPI clock %u kHz (AHB %u kHz / %u)\n",
  21686. + name,
  21687. + ahb_khz / div_real,
  21688. + ahb_khz, div_real);
  21689. + }
  21690. +
  21691. + return SPI_CTRL_FASTEST + div;
  21692. +}
  21693. +
  21694. +static int rb4xx_spi_probe(struct platform_device *pdev)
  21695. +{
  21696. + struct spi_master *master;
  21697. + struct rb4xx_spi *rbspi;
  21698. + struct resource *r;
  21699. + int err = 0;
  21700. +
  21701. + master = spi_alloc_master(&pdev->dev, sizeof(*rbspi));
  21702. + if (master == NULL) {
  21703. + dev_err(&pdev->dev, "no memory for spi_master\n");
  21704. + err = -ENOMEM;
  21705. + goto err_out;
  21706. + }
  21707. +
  21708. + master->bus_num = 0;
  21709. + master->num_chipselect = 3;
  21710. + master->setup = rb4xx_spi_setup;
  21711. + master->transfer = rb4xx_spi_transfer;
  21712. +
  21713. + rbspi = spi_master_get_devdata(master);
  21714. + platform_set_drvdata(pdev, rbspi);
  21715. +
  21716. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  21717. + if (r == NULL) {
  21718. + err = -ENOENT;
  21719. + goto err_put_master;
  21720. + }
  21721. +
  21722. + rbspi->base = ioremap(r->start, r->end - r->start + 1);
  21723. + if (!rbspi->base) {
  21724. + err = -ENXIO;
  21725. + goto err_put_master;
  21726. + }
  21727. +
  21728. + rbspi->master = master;
  21729. + rbspi->spi_ctrl_flash = get_spi_ctrl(SPI_FLASH_HZ, "FLASH");
  21730. + rbspi->spi_ctrl_fread = get_spi_ctrl(SPI_CPLD_HZ, "CPLD");
  21731. + rbspi->cs_wait = -1;
  21732. +
  21733. + spin_lock_init(&rbspi->lock);
  21734. + INIT_LIST_HEAD(&rbspi->queue);
  21735. +
  21736. + err = spi_register_master(master);
  21737. + if (err) {
  21738. + dev_err(&pdev->dev, "failed to register SPI master\n");
  21739. + goto err_iounmap;
  21740. + }
  21741. +
  21742. + return 0;
  21743. +
  21744. +err_iounmap:
  21745. + iounmap(rbspi->base);
  21746. +err_put_master:
  21747. + platform_set_drvdata(pdev, NULL);
  21748. + spi_master_put(master);
  21749. +err_out:
  21750. + return err;
  21751. +}
  21752. +
  21753. +static int rb4xx_spi_remove(struct platform_device *pdev)
  21754. +{
  21755. + struct rb4xx_spi *rbspi = platform_get_drvdata(pdev);
  21756. +
  21757. + iounmap(rbspi->base);
  21758. + platform_set_drvdata(pdev, NULL);
  21759. + spi_master_put(rbspi->master);
  21760. +
  21761. + return 0;
  21762. +}
  21763. +
  21764. +static struct platform_driver rb4xx_spi_drv = {
  21765. + .probe = rb4xx_spi_probe,
  21766. + .remove = rb4xx_spi_remove,
  21767. + .driver = {
  21768. + .name = DRV_NAME,
  21769. + .owner = THIS_MODULE,
  21770. + },
  21771. +};
  21772. +
  21773. +static int __init rb4xx_spi_init(void)
  21774. +{
  21775. + return platform_driver_register(&rb4xx_spi_drv);
  21776. +}
  21777. +subsys_initcall(rb4xx_spi_init);
  21778. +
  21779. +static void __exit rb4xx_spi_exit(void)
  21780. +{
  21781. + platform_driver_unregister(&rb4xx_spi_drv);
  21782. +}
  21783. +
  21784. +module_exit(rb4xx_spi_exit);
  21785. +
  21786. +MODULE_DESCRIPTION(DRV_DESC);
  21787. +MODULE_VERSION(DRV_VERSION);
  21788. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  21789. +MODULE_LICENSE("GPL v2");
  21790. diff -Nur linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c
  21791. --- linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c 1970-01-01 01:00:00.000000000 +0100
  21792. +++ linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c 2011-08-24 18:17:24.000000000 +0200
  21793. @@ -0,0 +1,440 @@
  21794. +/*
  21795. + * SPI driver for the CPLD chip on the Mikrotik RB4xx boards
  21796. + *
  21797. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  21798. + *
  21799. + * This file was based on the patches for Linux 2.6.27.39 published by
  21800. + * MikroTik for their RouterBoard 4xx series devices.
  21801. + *
  21802. + * This program is free software; you can redistribute it and/or modify it
  21803. + * under the terms of the GNU General Public License version 2 as published
  21804. + * by the Free Software Foundation.
  21805. + */
  21806. +
  21807. +#include <linux/types.h>
  21808. +#include <linux/kernel.h>
  21809. +#include <linux/init.h>
  21810. +#include <linux/module.h>
  21811. +#include <linux/device.h>
  21812. +#include <linux/bitops.h>
  21813. +#include <linux/spi/spi.h>
  21814. +#include <linux/gpio.h>
  21815. +#include <linux/slab.h>
  21816. +
  21817. +#include <asm/mach-ar71xx/rb4xx_cpld.h>
  21818. +
  21819. +#define DRV_NAME "spi-rb4xx-cpld"
  21820. +#define DRV_DESC "RB4xx CPLD driver"
  21821. +#define DRV_VERSION "0.1.0"
  21822. +
  21823. +#define CPLD_CMD_WRITE_NAND 0x08 /* send cmd, n x send data, send indle */
  21824. +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */
  21825. +#define CPLD_CMD_READ_NAND 0x0a /* send cmd, send idle, n x read data */
  21826. +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */
  21827. +#define CPLD_CMD_LED5_ON 0x0c /* send cmd */
  21828. +#define CPLD_CMD_LED5_OFF 0x0d /* send cmd */
  21829. +
  21830. +struct rb4xx_cpld {
  21831. + struct spi_device *spi;
  21832. + struct mutex lock;
  21833. + struct gpio_chip chip;
  21834. + unsigned int config;
  21835. +};
  21836. +
  21837. +static struct rb4xx_cpld *rb4xx_cpld;
  21838. +
  21839. +static inline struct rb4xx_cpld *gpio_to_cpld(struct gpio_chip *chip)
  21840. +{
  21841. + return container_of(chip, struct rb4xx_cpld, chip);
  21842. +}
  21843. +
  21844. +static int rb4xx_cpld_write_cmd(struct rb4xx_cpld *cpld, unsigned char cmd)
  21845. +{
  21846. + struct spi_transfer t[1];
  21847. + struct spi_message m;
  21848. + unsigned char tx_buf[1];
  21849. + int err;
  21850. +
  21851. + spi_message_init(&m);
  21852. + memset(&t, 0, sizeof(t));
  21853. +
  21854. + t[0].tx_buf = tx_buf;
  21855. + t[0].len = sizeof(tx_buf);
  21856. + spi_message_add_tail(&t[0], &m);
  21857. +
  21858. + tx_buf[0] = cmd;
  21859. +
  21860. + err = spi_sync(cpld->spi, &m);
  21861. + return err;
  21862. +}
  21863. +
  21864. +static int rb4xx_cpld_write_cfg(struct rb4xx_cpld *cpld, unsigned char config)
  21865. +{
  21866. + struct spi_transfer t[1];
  21867. + struct spi_message m;
  21868. + unsigned char cmd[2];
  21869. + int err;
  21870. +
  21871. + spi_message_init(&m);
  21872. + memset(&t, 0, sizeof(t));
  21873. +
  21874. + t[0].tx_buf = cmd;
  21875. + t[0].len = sizeof(cmd);
  21876. + spi_message_add_tail(&t[0], &m);
  21877. +
  21878. + cmd[0] = CPLD_CMD_WRITE_CFG;
  21879. + cmd[1] = config;
  21880. +
  21881. + err = spi_sync(cpld->spi, &m);
  21882. + return err;
  21883. +}
  21884. +
  21885. +static int __rb4xx_cpld_change_cfg(struct rb4xx_cpld *cpld, unsigned mask,
  21886. + unsigned value)
  21887. +{
  21888. + unsigned int config;
  21889. + int err;
  21890. +
  21891. + config = cpld->config & ~mask;
  21892. + config |= value;
  21893. +
  21894. + if ((cpld->config ^ config) & 0xff) {
  21895. + err = rb4xx_cpld_write_cfg(cpld, config);
  21896. + if (err)
  21897. + return err;
  21898. + }
  21899. +
  21900. + if ((cpld->config ^ config) & CPLD_CFG_nLED5) {
  21901. + err = rb4xx_cpld_write_cmd(cpld, (value) ? CPLD_CMD_LED5_ON :
  21902. + CPLD_CMD_LED5_OFF);
  21903. + if (err)
  21904. + return err;
  21905. + }
  21906. +
  21907. + cpld->config = config;
  21908. + return 0;
  21909. +}
  21910. +
  21911. +int rb4xx_cpld_change_cfg(unsigned mask, unsigned value)
  21912. +{
  21913. + int ret;
  21914. +
  21915. + if (rb4xx_cpld == NULL)
  21916. + return -ENODEV;
  21917. +
  21918. + mutex_lock(&rb4xx_cpld->lock);
  21919. + ret = __rb4xx_cpld_change_cfg(rb4xx_cpld, mask, value);
  21920. + mutex_unlock(&rb4xx_cpld->lock);
  21921. +
  21922. + return ret;
  21923. +}
  21924. +EXPORT_SYMBOL_GPL(rb4xx_cpld_change_cfg);
  21925. +
  21926. +int rb4xx_cpld_read_from(unsigned addr, unsigned char *rx_buf,
  21927. + const unsigned char *verify_buf, unsigned count)
  21928. +{
  21929. + const unsigned char cmd[5] = {
  21930. + CPLD_CMD_READ_FAST,
  21931. + (addr >> 16) & 0xff,
  21932. + (addr >> 8) & 0xff,
  21933. + addr & 0xff,
  21934. + 0
  21935. + };
  21936. + struct spi_transfer t[2] = {
  21937. + {
  21938. + .tx_buf = &cmd,
  21939. + .len = 5,
  21940. + },
  21941. + {
  21942. + .tx_buf = verify_buf,
  21943. + .rx_buf = rx_buf,
  21944. + .len = count,
  21945. + .verify = (verify_buf != NULL),
  21946. + },
  21947. + };
  21948. + struct spi_message m;
  21949. +
  21950. + if (rb4xx_cpld == NULL)
  21951. + return -ENODEV;
  21952. +
  21953. + spi_message_init(&m);
  21954. + m.fast_read = 1;
  21955. + spi_message_add_tail(&t[0], &m);
  21956. + spi_message_add_tail(&t[1], &m);
  21957. + return spi_sync(rb4xx_cpld->spi, &m);
  21958. +}
  21959. +EXPORT_SYMBOL_GPL(rb4xx_cpld_read_from);
  21960. +
  21961. +#if 0
  21962. +int rb4xx_cpld_read(unsigned char *buf, unsigned char *verify_buf,
  21963. + unsigned count)
  21964. +{
  21965. + struct spi_transfer t[2];
  21966. + struct spi_message m;
  21967. + unsigned char cmd[2];
  21968. +
  21969. + if (rb4xx_cpld == NULL)
  21970. + return -ENODEV;
  21971. +
  21972. + spi_message_init(&m);
  21973. + memset(&t, 0, sizeof(t));
  21974. +
  21975. + /* send command */
  21976. + t[0].tx_buf = cmd;
  21977. + t[0].len = sizeof(cmd);
  21978. + spi_message_add_tail(&t[0], &m);
  21979. +
  21980. + cmd[0] = CPLD_CMD_READ_NAND;
  21981. + cmd[1] = 0;
  21982. +
  21983. + /* read data */
  21984. + t[1].rx_buf = buf;
  21985. + t[1].len = count;
  21986. + spi_message_add_tail(&t[1], &m);
  21987. +
  21988. + return spi_sync(rb4xx_cpld->spi, &m);
  21989. +}
  21990. +#else
  21991. +int rb4xx_cpld_read(unsigned char *rx_buf, const unsigned char *verify_buf,
  21992. + unsigned count)
  21993. +{
  21994. + static const unsigned char cmd[2] = { CPLD_CMD_READ_NAND, 0 };
  21995. + struct spi_transfer t[2] = {
  21996. + {
  21997. + .tx_buf = &cmd,
  21998. + .len = 2,
  21999. + }, {
  22000. + .tx_buf = verify_buf,
  22001. + .rx_buf = rx_buf,
  22002. + .len = count,
  22003. + .verify = (verify_buf != NULL),
  22004. + },
  22005. + };
  22006. + struct spi_message m;
  22007. +
  22008. + if (rb4xx_cpld == NULL)
  22009. + return -ENODEV;
  22010. +
  22011. + spi_message_init(&m);
  22012. + spi_message_add_tail(&t[0], &m);
  22013. + spi_message_add_tail(&t[1], &m);
  22014. + return spi_sync(rb4xx_cpld->spi, &m);
  22015. +}
  22016. +#endif
  22017. +EXPORT_SYMBOL_GPL(rb4xx_cpld_read);
  22018. +
  22019. +int rb4xx_cpld_write(const unsigned char *buf, unsigned count)
  22020. +{
  22021. +#if 0
  22022. + struct spi_transfer t[3];
  22023. + struct spi_message m;
  22024. + unsigned char cmd[1];
  22025. +
  22026. + if (rb4xx_cpld == NULL)
  22027. + return -ENODEV;
  22028. +
  22029. + memset(&t, 0, sizeof(t));
  22030. + spi_message_init(&m);
  22031. +
  22032. + /* send command */
  22033. + t[0].tx_buf = cmd;
  22034. + t[0].len = sizeof(cmd);
  22035. + spi_message_add_tail(&t[0], &m);
  22036. +
  22037. + cmd[0] = CPLD_CMD_WRITE_NAND;
  22038. +
  22039. + /* write data */
  22040. + t[1].tx_buf = buf;
  22041. + t[1].len = count;
  22042. + spi_message_add_tail(&t[1], &m);
  22043. +
  22044. + /* send idle */
  22045. + t[2].len = 1;
  22046. + spi_message_add_tail(&t[2], &m);
  22047. +
  22048. + return spi_sync(rb4xx_cpld->spi, &m);
  22049. +#else
  22050. + static const unsigned char cmd = CPLD_CMD_WRITE_NAND;
  22051. + struct spi_transfer t[3] = {
  22052. + {
  22053. + .tx_buf = &cmd,
  22054. + .len = 1,
  22055. + }, {
  22056. + .tx_buf = buf,
  22057. + .len = count,
  22058. + .fast_write = 1,
  22059. + }, {
  22060. + .len = 1,
  22061. + .fast_write = 1,
  22062. + },
  22063. + };
  22064. + struct spi_message m;
  22065. +
  22066. + if (rb4xx_cpld == NULL)
  22067. + return -ENODEV;
  22068. +
  22069. + spi_message_init(&m);
  22070. + spi_message_add_tail(&t[0], &m);
  22071. + spi_message_add_tail(&t[1], &m);
  22072. + spi_message_add_tail(&t[2], &m);
  22073. + return spi_sync(rb4xx_cpld->spi, &m);
  22074. +#endif
  22075. +}
  22076. +EXPORT_SYMBOL_GPL(rb4xx_cpld_write);
  22077. +
  22078. +static int rb4xx_cpld_gpio_get(struct gpio_chip *chip, unsigned offset)
  22079. +{
  22080. + struct rb4xx_cpld *cpld = gpio_to_cpld(chip);
  22081. + int ret;
  22082. +
  22083. + mutex_lock(&cpld->lock);
  22084. + ret = (cpld->config >> offset) & 1;
  22085. + mutex_unlock(&cpld->lock);
  22086. +
  22087. + return ret;
  22088. +}
  22089. +
  22090. +static void rb4xx_cpld_gpio_set(struct gpio_chip *chip, unsigned offset,
  22091. + int value)
  22092. +{
  22093. + struct rb4xx_cpld *cpld = gpio_to_cpld(chip);
  22094. +
  22095. + mutex_lock(&cpld->lock);
  22096. + __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset);
  22097. + mutex_unlock(&cpld->lock);
  22098. +}
  22099. +
  22100. +static int rb4xx_cpld_gpio_direction_input(struct gpio_chip *chip,
  22101. + unsigned offset)
  22102. +{
  22103. + return -EOPNOTSUPP;
  22104. +}
  22105. +
  22106. +static int rb4xx_cpld_gpio_direction_output(struct gpio_chip *chip,
  22107. + unsigned offset,
  22108. + int value)
  22109. +{
  22110. + struct rb4xx_cpld *cpld = gpio_to_cpld(chip);
  22111. + int ret;
  22112. +
  22113. + mutex_lock(&cpld->lock);
  22114. + ret = __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset);
  22115. + mutex_unlock(&cpld->lock);
  22116. +
  22117. + return ret;
  22118. +}
  22119. +
  22120. +static int rb4xx_cpld_gpio_init(struct rb4xx_cpld *cpld, unsigned int base)
  22121. +{
  22122. + int err;
  22123. +
  22124. + /* init config */
  22125. + cpld->config = CPLD_CFG_nLED1 | CPLD_CFG_nLED2 | CPLD_CFG_nLED3 |
  22126. + CPLD_CFG_nLED4 | CPLD_CFG_nCE;
  22127. + rb4xx_cpld_write_cfg(cpld, cpld->config);
  22128. +
  22129. + /* setup GPIO chip */
  22130. + cpld->chip.label = DRV_NAME;
  22131. +
  22132. + cpld->chip.get = rb4xx_cpld_gpio_get;
  22133. + cpld->chip.set = rb4xx_cpld_gpio_set;
  22134. + cpld->chip.direction_input = rb4xx_cpld_gpio_direction_input;
  22135. + cpld->chip.direction_output = rb4xx_cpld_gpio_direction_output;
  22136. +
  22137. + cpld->chip.base = base;
  22138. + cpld->chip.ngpio = CPLD_NUM_GPIOS;
  22139. + cpld->chip.can_sleep = 1;
  22140. + cpld->chip.dev = &cpld->spi->dev;
  22141. + cpld->chip.owner = THIS_MODULE;
  22142. +
  22143. + err = gpiochip_add(&cpld->chip);
  22144. + if (err)
  22145. + dev_err(&cpld->spi->dev, "adding GPIO chip failed, err=%d\n",
  22146. + err);
  22147. +
  22148. + return err;
  22149. +}
  22150. +
  22151. +static int __devinit rb4xx_cpld_probe(struct spi_device *spi)
  22152. +{
  22153. + struct rb4xx_cpld *cpld;
  22154. + struct rb4xx_cpld_platform_data *pdata;
  22155. + int err;
  22156. +
  22157. + pdata = spi->dev.platform_data;
  22158. + if (!pdata) {
  22159. + dev_dbg(&spi->dev, "no platform data\n");
  22160. + return -EINVAL;
  22161. + }
  22162. +
  22163. + cpld = kzalloc(sizeof(*cpld), GFP_KERNEL);
  22164. + if (!cpld) {
  22165. + dev_err(&spi->dev, "no memory for private data\n");
  22166. + return -ENOMEM;
  22167. + }
  22168. +
  22169. + mutex_init(&cpld->lock);
  22170. + cpld->spi = spi_dev_get(spi);
  22171. + dev_set_drvdata(&spi->dev, cpld);
  22172. +
  22173. + spi->mode = SPI_MODE_0;
  22174. + spi->bits_per_word = 8;
  22175. + err = spi_setup(spi);
  22176. + if (err) {
  22177. + dev_err(&spi->dev, "spi_setup failed, err=%d\n", err);
  22178. + goto err_drvdata;
  22179. + }
  22180. +
  22181. + err = rb4xx_cpld_gpio_init(cpld, pdata->gpio_base);
  22182. + if (err)
  22183. + goto err_drvdata;
  22184. +
  22185. + rb4xx_cpld = cpld;
  22186. +
  22187. + return 0;
  22188. +
  22189. +err_drvdata:
  22190. + dev_set_drvdata(&spi->dev, NULL);
  22191. + kfree(cpld);
  22192. +
  22193. + return err;
  22194. +}
  22195. +
  22196. +static int __devexit rb4xx_cpld_remove(struct spi_device *spi)
  22197. +{
  22198. + struct rb4xx_cpld *cpld;
  22199. +
  22200. + rb4xx_cpld = NULL;
  22201. + cpld = dev_get_drvdata(&spi->dev);
  22202. + dev_set_drvdata(&spi->dev, NULL);
  22203. + kfree(cpld);
  22204. +
  22205. + return 0;
  22206. +}
  22207. +
  22208. +static struct spi_driver rb4xx_cpld_driver = {
  22209. + .driver = {
  22210. + .name = DRV_NAME,
  22211. + .bus = &spi_bus_type,
  22212. + .owner = THIS_MODULE,
  22213. + },
  22214. + .probe = rb4xx_cpld_probe,
  22215. + .remove = __devexit_p(rb4xx_cpld_remove),
  22216. +};
  22217. +
  22218. +static int __init rb4xx_cpld_init(void)
  22219. +{
  22220. + return spi_register_driver(&rb4xx_cpld_driver);
  22221. +}
  22222. +module_init(rb4xx_cpld_init);
  22223. +
  22224. +static void __exit rb4xx_cpld_exit(void)
  22225. +{
  22226. + spi_unregister_driver(&rb4xx_cpld_driver);
  22227. +}
  22228. +module_exit(rb4xx_cpld_exit);
  22229. +
  22230. +MODULE_DESCRIPTION(DRV_DESC);
  22231. +MODULE_VERSION(DRV_VERSION);
  22232. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  22233. +MODULE_LICENSE("GPL v2");
  22234. diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/spi_vsc7385.c
  22235. --- linux-2.6.39.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100
  22236. +++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-08-24 18:17:24.000000000 +0200
  22237. @@ -0,0 +1,621 @@
  22238. +/*
  22239. + * SPI driver for the Vitesse VSC7385 ethernet switch
  22240. + *
  22241. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  22242. + *
  22243. + * Parts of this file are based on Atheros' 2.6.15 BSP
  22244. + *
  22245. + * This program is free software; you can redistribute it and/or modify it
  22246. + * under the terms of the GNU General Public License version 2 as published
  22247. + * by the Free Software Foundation.
  22248. + */
  22249. +
  22250. +#include <linux/types.h>
  22251. +#include <linux/kernel.h>
  22252. +#include <linux/init.h>
  22253. +#include <linux/module.h>
  22254. +#include <linux/delay.h>
  22255. +#include <linux/device.h>
  22256. +#include <linux/bitops.h>
  22257. +#include <linux/firmware.h>
  22258. +#include <linux/spi/spi.h>
  22259. +#include <linux/spi/vsc7385.h>
  22260. +
  22261. +#define DRV_NAME "spi-vsc7385"
  22262. +#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver"
  22263. +#define DRV_VERSION "0.1.0"
  22264. +
  22265. +#define VSC73XX_BLOCK_MAC 0x1
  22266. +#define VSC73XX_BLOCK_2 0x2
  22267. +#define VSC73XX_BLOCK_MII 0x3
  22268. +#define VSC73XX_BLOCK_4 0x4
  22269. +#define VSC73XX_BLOCK_5 0x5
  22270. +#define VSC73XX_BLOCK_SYSTEM 0x7
  22271. +
  22272. +#define VSC73XX_SUBBLOCK_PORT_0 0
  22273. +#define VSC73XX_SUBBLOCK_PORT_1 1
  22274. +#define VSC73XX_SUBBLOCK_PORT_2 2
  22275. +#define VSC73XX_SUBBLOCK_PORT_3 3
  22276. +#define VSC73XX_SUBBLOCK_PORT_4 4
  22277. +#define VSC73XX_SUBBLOCK_PORT_MAC 6
  22278. +
  22279. +/* MAC Block registers */
  22280. +#define VSC73XX_MAC_CFG 0x0
  22281. +#define VSC73XX_ADVPORTM 0x19
  22282. +#define VSC73XX_RXOCT 0x50
  22283. +#define VSC73XX_TXOCT 0x51
  22284. +#define VSC73XX_C_RX0 0x52
  22285. +#define VSC73XX_C_RX1 0x53
  22286. +#define VSC73XX_C_RX2 0x54
  22287. +#define VSC73XX_C_TX0 0x55
  22288. +#define VSC73XX_C_TX1 0x56
  22289. +#define VSC73XX_C_TX2 0x57
  22290. +#define VSC73XX_C_CFG 0x58
  22291. +
  22292. +/* MAC_CFG register bits */
  22293. +#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31)
  22294. +#define VSC73XX_MAC_CFG_PORT_RST (1 << 29)
  22295. +#define VSC73XX_MAC_CFG_TX_EN (1 << 28)
  22296. +#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27)
  22297. +#define VSC73XX_MAC_CFG_FDX (1 << 18)
  22298. +#define VSC73XX_MAC_CFG_GIGE (1 << 17)
  22299. +#define VSC73XX_MAC_CFG_RX_EN (1 << 16)
  22300. +#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15)
  22301. +#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14)
  22302. +#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13)
  22303. +#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6)
  22304. +#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5)
  22305. +#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4)
  22306. +#define VSC73XX_MAC_CFG_BIT2 (1 << 2)
  22307. +#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3)
  22308. +
  22309. +/* ADVPORTM register bits */
  22310. +#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7)
  22311. +#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6)
  22312. +#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5)
  22313. +#define VSC73XX_ADVPORTM_INV_GTX (1 << 4)
  22314. +#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3)
  22315. +#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2)
  22316. +#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1)
  22317. +#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0)
  22318. +
  22319. +/* MII Block registers */
  22320. +#define VSC73XX_MII_STAT 0x0
  22321. +#define VSC73XX_MII_CMD 0x1
  22322. +#define VSC73XX_MII_DATA 0x2
  22323. +
  22324. +/* System Block registers */
  22325. +#define VSC73XX_ICPU_SIPAD 0x01
  22326. +#define VSC73XX_ICPU_CLOCK_DELAY 0x05
  22327. +#define VSC73XX_ICPU_CTRL 0x10
  22328. +#define VSC73XX_ICPU_ADDR 0x11
  22329. +#define VSC73XX_ICPU_SRAM 0x12
  22330. +#define VSC73XX_ICPU_MBOX_VAL 0x15
  22331. +#define VSC73XX_ICPU_MBOX_SET 0x16
  22332. +#define VSC73XX_ICPU_MBOX_CLR 0x17
  22333. +#define VSC73XX_ICPU_CHIPID 0x18
  22334. +#define VSC73XX_ICPU_GPIO 0x34
  22335. +
  22336. +#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8)
  22337. +#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7)
  22338. +#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3)
  22339. +#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2)
  22340. +#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1)
  22341. +#define VSC73XX_ICPU_CTRL_SRST (1 << 0)
  22342. +
  22343. +#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12
  22344. +#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff
  22345. +#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28
  22346. +#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf
  22347. +#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385
  22348. +#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395
  22349. +
  22350. +#define VSC73XX_CMD_MODE_READ 0
  22351. +#define VSC73XX_CMD_MODE_WRITE 1
  22352. +#define VSC73XX_CMD_MODE_SHIFT 4
  22353. +#define VSC73XX_CMD_BLOCK_SHIFT 5
  22354. +#define VSC73XX_CMD_BLOCK_MASK 0x7
  22355. +#define VSC73XX_CMD_SUBBLOCK_MASK 0xf
  22356. +
  22357. +#define VSC7385_CLOCK_DELAY ((3 << 4) | 3)
  22358. +#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3)
  22359. +
  22360. +#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \
  22361. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  22362. + VSC73XX_ICPU_CTRL_EXT_ACC_EN)
  22363. +
  22364. +#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \
  22365. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  22366. + VSC73XX_ICPU_CTRL_CLK_EN | \
  22367. + VSC73XX_ICPU_CTRL_SRST)
  22368. +
  22369. +#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \
  22370. + VSC73XX_ADVPORTM_EXC_COL_CONT | \
  22371. + VSC73XX_ADVPORTM_EXT_PORT | \
  22372. + VSC73XX_ADVPORTM_INV_GTX | \
  22373. + VSC73XX_ADVPORTM_ENA_GTX | \
  22374. + VSC73XX_ADVPORTM_DDR_MODE | \
  22375. + VSC73XX_ADVPORTM_IO_LOOPBACK | \
  22376. + VSC73XX_ADVPORTM_HOST_LOOPBACK)
  22377. +
  22378. +#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \
  22379. + VSC73XX_ADVPORTM_ENA_GTX | \
  22380. + VSC73XX_ADVPORTM_DDR_MODE)
  22381. +
  22382. +#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \
  22383. + VSC73XX_MAC_CFG_MAC_RX_RST | \
  22384. + VSC73XX_MAC_CFG_MAC_TX_RST)
  22385. +
  22386. +#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \
  22387. + VSC73XX_MAC_CFG_FDX | \
  22388. + VSC73XX_MAC_CFG_GIGE | \
  22389. + VSC73XX_MAC_CFG_RX_EN)
  22390. +
  22391. +#define VSC73XX_RESET_DELAY 100
  22392. +
  22393. +struct vsc7385 {
  22394. + struct spi_device *spi;
  22395. + struct mutex lock;
  22396. + struct vsc7385_platform_data *pdata;
  22397. +};
  22398. +
  22399. +static int vsc7385_is_addr_valid(u8 block, u8 subblock)
  22400. +{
  22401. + switch (block) {
  22402. + case VSC73XX_BLOCK_MAC:
  22403. + switch (subblock) {
  22404. + case 0 ... 4:
  22405. + case 6:
  22406. + return 1;
  22407. + }
  22408. + break;
  22409. +
  22410. + case VSC73XX_BLOCK_2:
  22411. + case VSC73XX_BLOCK_SYSTEM:
  22412. + switch (subblock) {
  22413. + case 0:
  22414. + return 1;
  22415. + }
  22416. + break;
  22417. +
  22418. + case VSC73XX_BLOCK_MII:
  22419. + case VSC73XX_BLOCK_4:
  22420. + case VSC73XX_BLOCK_5:
  22421. + switch (subblock) {
  22422. + case 0 ... 1:
  22423. + return 1;
  22424. + }
  22425. + break;
  22426. + }
  22427. +
  22428. + return 0;
  22429. +}
  22430. +
  22431. +static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock)
  22432. +{
  22433. + u8 ret;
  22434. +
  22435. + ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT;
  22436. + ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT;
  22437. + ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK;
  22438. +
  22439. + return ret;
  22440. +}
  22441. +
  22442. +static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  22443. + u32 *value)
  22444. +{
  22445. + u8 cmd[4];
  22446. + u8 buf[4];
  22447. + struct spi_transfer t[2];
  22448. + struct spi_message m;
  22449. + int err;
  22450. +
  22451. + if (!vsc7385_is_addr_valid(block, subblock))
  22452. + return -EINVAL;
  22453. +
  22454. + spi_message_init(&m);
  22455. +
  22456. + memset(&t, 0, sizeof(t));
  22457. +
  22458. + t[0].tx_buf = cmd;
  22459. + t[0].len = sizeof(cmd);
  22460. + spi_message_add_tail(&t[0], &m);
  22461. +
  22462. + t[1].rx_buf = buf;
  22463. + t[1].len = sizeof(buf);
  22464. + spi_message_add_tail(&t[1], &m);
  22465. +
  22466. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock);
  22467. + cmd[1] = reg;
  22468. + cmd[2] = 0;
  22469. + cmd[3] = 0;
  22470. +
  22471. + mutex_lock(&vsc->lock);
  22472. + err = spi_sync(vsc->spi, &m);
  22473. + mutex_unlock(&vsc->lock);
  22474. +
  22475. + if (err)
  22476. + return err;
  22477. +
  22478. + *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) |
  22479. + (((u32) buf[2]) << 8) | ((u32) buf[3]);
  22480. +
  22481. + return 0;
  22482. +}
  22483. +
  22484. +
  22485. +static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  22486. + u32 value)
  22487. +{
  22488. + u8 cmd[2];
  22489. + u8 buf[4];
  22490. + struct spi_transfer t[2];
  22491. + struct spi_message m;
  22492. + int err;
  22493. +
  22494. + if (!vsc7385_is_addr_valid(block, subblock))
  22495. + return -EINVAL;
  22496. +
  22497. + spi_message_init(&m);
  22498. +
  22499. + memset(&t, 0, sizeof(t));
  22500. +
  22501. + t[0].tx_buf = cmd;
  22502. + t[0].len = sizeof(cmd);
  22503. + spi_message_add_tail(&t[0], &m);
  22504. +
  22505. + t[1].tx_buf = buf;
  22506. + t[1].len = sizeof(buf);
  22507. + spi_message_add_tail(&t[1], &m);
  22508. +
  22509. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock);
  22510. + cmd[1] = reg;
  22511. +
  22512. + buf[0] = (value >> 24) & 0xff;
  22513. + buf[1] = (value >> 16) & 0xff;
  22514. + buf[2] = (value >> 8) & 0xff;
  22515. + buf[3] = value & 0xff;
  22516. +
  22517. + mutex_lock(&vsc->lock);
  22518. + err = spi_sync(vsc->spi, &m);
  22519. + mutex_unlock(&vsc->lock);
  22520. +
  22521. + return err;
  22522. +}
  22523. +
  22524. +static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block,
  22525. + u8 subblock, u8 reg, u32 value,
  22526. + u32 read_mask, u32 read_val)
  22527. +{
  22528. + struct spi_device *spi = vsc->spi;
  22529. + u32 t;
  22530. + int err;
  22531. +
  22532. + err = vsc7385_write(vsc, block, subblock, reg, value);
  22533. + if (err)
  22534. + return err;
  22535. +
  22536. + err = vsc7385_read(vsc, block, subblock, reg, &t);
  22537. + if (err)
  22538. + return err;
  22539. +
  22540. + if ((t & read_mask) != read_val) {
  22541. + dev_err(&spi->dev, "register write error\n");
  22542. + return -EIO;
  22543. + }
  22544. +
  22545. + return 0;
  22546. +}
  22547. +
  22548. +static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val)
  22549. +{
  22550. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22551. + VSC73XX_ICPU_CLOCK_DELAY, val);
  22552. +}
  22553. +
  22554. +static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val)
  22555. +{
  22556. + return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22557. + VSC73XX_ICPU_CLOCK_DELAY, val);
  22558. +}
  22559. +
  22560. +static inline int vsc7385_icpu_stop(struct vsc7385 *vsc)
  22561. +{
  22562. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  22563. + VSC73XX_ICPU_CTRL_STOP);
  22564. +}
  22565. +
  22566. +static inline int vsc7385_icpu_start(struct vsc7385 *vsc)
  22567. +{
  22568. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  22569. + VSC73XX_ICPU_CTRL_START);
  22570. +}
  22571. +
  22572. +static inline int vsc7385_icpu_reset(struct vsc7385 *vsc)
  22573. +{
  22574. + int rc;
  22575. +
  22576. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR,
  22577. + 0x0000);
  22578. + if (rc)
  22579. + dev_err(&vsc->spi->dev,
  22580. + "could not reset microcode, err=%d\n", rc);
  22581. +
  22582. + return rc;
  22583. +}
  22584. +
  22585. +static int vsc7385_upload_ucode(struct vsc7385 *vsc)
  22586. +{
  22587. + struct spi_device *spi = vsc->spi;
  22588. + const struct firmware *firmware;
  22589. + char *ucode_name;
  22590. + unsigned char *dp;
  22591. + unsigned int curVal;
  22592. + int i;
  22593. + int diffs;
  22594. + int rc;
  22595. +
  22596. + ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name
  22597. + : "vsc7385_ucode.bin";
  22598. + rc = request_firmware(&firmware, ucode_name, &spi->dev);
  22599. + if (rc) {
  22600. + dev_err(&spi->dev, "request_firmware failed, err=%d\n",
  22601. + rc);
  22602. + return rc;
  22603. + }
  22604. +
  22605. + rc = vsc7385_icpu_stop(vsc);
  22606. + if (rc)
  22607. + goto out;
  22608. +
  22609. + rc = vsc7385_icpu_reset(vsc);
  22610. + if (rc)
  22611. + goto out;
  22612. +
  22613. + dev_info(&spi->dev, "uploading microcode...\n");
  22614. +
  22615. + dp = (unsigned char *) firmware->data;
  22616. + for (i = 0; i < firmware->size; i++) {
  22617. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22618. + VSC73XX_ICPU_SRAM, *dp++);
  22619. + if (rc) {
  22620. + dev_err(&spi->dev, "could not load microcode, err=%d\n",
  22621. + rc);
  22622. + goto out;
  22623. + }
  22624. + }
  22625. +
  22626. + rc = vsc7385_icpu_reset(vsc);
  22627. + if (rc)
  22628. + goto out;
  22629. +
  22630. + dev_info(&spi->dev, "verifying microcode...\n");
  22631. +
  22632. + dp = (unsigned char *) firmware->data;
  22633. + diffs = 0;
  22634. + for (i = 0; i < firmware->size; i++) {
  22635. + rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22636. + VSC73XX_ICPU_SRAM, &curVal);
  22637. + if (rc) {
  22638. + dev_err(&spi->dev, "could not read microcode %d\n",
  22639. + rc);
  22640. + goto out;
  22641. + }
  22642. +
  22643. + if (curVal > 0xff) {
  22644. + dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n",
  22645. + i, *dp, curVal);
  22646. + rc = -EIO;
  22647. + goto out;
  22648. + }
  22649. +
  22650. + if ((curVal & 0xff) != *dp) {
  22651. + diffs++;
  22652. + dev_err(&spi->dev, "verify error: %04x : %02x %02x\n",
  22653. + i, *dp, curVal);
  22654. +
  22655. + if (diffs > 4)
  22656. + break;
  22657. + }
  22658. + dp++;
  22659. + }
  22660. +
  22661. + if (diffs) {
  22662. + dev_err(&spi->dev, "microcode verification failed\n");
  22663. + rc = -EIO;
  22664. + goto out;
  22665. + }
  22666. +
  22667. + dev_info(&spi->dev, "microcode uploaded\n");
  22668. +
  22669. + rc = vsc7385_icpu_start(vsc);
  22670. +
  22671. +out:
  22672. + release_firmware(firmware);
  22673. + return rc;
  22674. +}
  22675. +
  22676. +static int vsc7385_setup(struct vsc7385 *vsc)
  22677. +{
  22678. + struct vsc7385_platform_data *pdata = vsc->pdata;
  22679. + u32 t;
  22680. + int err;
  22681. +
  22682. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22683. + VSC73XX_ICPU_CLOCK_DELAY,
  22684. + VSC7385_CLOCK_DELAY,
  22685. + VSC7385_CLOCK_DELAY_MASK,
  22686. + VSC7385_CLOCK_DELAY);
  22687. + if (err)
  22688. + goto err;
  22689. +
  22690. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC,
  22691. + VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM,
  22692. + VSC7385_ADVPORTM_INIT,
  22693. + VSC7385_ADVPORTM_MASK,
  22694. + VSC7385_ADVPORTM_INIT);
  22695. + if (err)
  22696. + goto err;
  22697. +
  22698. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  22699. + VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET);
  22700. + if (err)
  22701. + goto err;
  22702. +
  22703. + t = VSC73XX_MAC_CFG_INIT;
  22704. + t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg);
  22705. + t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel);
  22706. + if (pdata->mac_cfg.bit2)
  22707. + t |= VSC73XX_MAC_CFG_BIT2;
  22708. +
  22709. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  22710. + VSC73XX_MAC_CFG, t);
  22711. + if (err)
  22712. + goto err;
  22713. +
  22714. + return 0;
  22715. +
  22716. +err:
  22717. + return err;
  22718. +}
  22719. +
  22720. +static int vsc7385_detect(struct vsc7385 *vsc)
  22721. +{
  22722. + struct spi_device *spi = vsc->spi;
  22723. + u32 t;
  22724. + u32 id;
  22725. + u32 rev;
  22726. + int err;
  22727. +
  22728. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22729. + VSC73XX_ICPU_MBOX_VAL, &t);
  22730. + if (err) {
  22731. + dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err);
  22732. + return err;
  22733. + }
  22734. +
  22735. + if (t == 0xffffffff) {
  22736. + dev_dbg(&spi->dev, "assert chip reset\n");
  22737. + if (vsc->pdata->reset)
  22738. + vsc->pdata->reset();
  22739. +
  22740. + }
  22741. +
  22742. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  22743. + VSC73XX_ICPU_CHIPID, &t);
  22744. + if (err) {
  22745. + dev_err(&spi->dev, "unable to read chip id, err=%d\n", err);
  22746. + return err;
  22747. + }
  22748. +
  22749. + id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK;
  22750. + switch (id) {
  22751. + case VSC73XX_ICPU_CHIPID_ID_7385:
  22752. + case VSC73XX_ICPU_CHIPID_ID_7395:
  22753. + break;
  22754. + default:
  22755. + dev_err(&spi->dev, "unsupported chip, id=%04x\n", id);
  22756. + return -ENODEV;
  22757. + }
  22758. +
  22759. + rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) &
  22760. + VSC73XX_ICPU_CHIPID_REV_MASK;
  22761. + dev_info(&spi->dev, "VSC%04X (rev. %d) switch found\n", id, rev);
  22762. +
  22763. + return 0;
  22764. +}
  22765. +
  22766. +static int __devinit vsc7385_probe(struct spi_device *spi)
  22767. +{
  22768. + struct vsc7385 *vsc;
  22769. + struct vsc7385_platform_data *pdata;
  22770. + int err;
  22771. +
  22772. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
  22773. +
  22774. + pdata = spi->dev.platform_data;
  22775. + if (!pdata) {
  22776. + dev_err(&spi->dev, "no platform data specified\n");
  22777. + return -ENODEV;
  22778. + }
  22779. +
  22780. + vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
  22781. + if (!vsc) {
  22782. + dev_err(&spi->dev, "no memory for private data\n");
  22783. + return -ENOMEM;
  22784. + }
  22785. +
  22786. + mutex_init(&vsc->lock);
  22787. + vsc->pdata = pdata;
  22788. + vsc->spi = spi_dev_get(spi);
  22789. + dev_set_drvdata(&spi->dev, vsc);
  22790. +
  22791. + spi->mode = SPI_MODE_0;
  22792. + spi->bits_per_word = 8;
  22793. + err = spi_setup(spi);
  22794. + if (err) {
  22795. + dev_err(&spi->dev, "spi_setup failed, err=%d\n", err);
  22796. + goto err_drvdata;
  22797. + }
  22798. +
  22799. + err = vsc7385_detect(vsc);
  22800. + if (err) {
  22801. + dev_err(&spi->dev, "no chip found, err=%d\n", err);
  22802. + goto err_drvdata;
  22803. + }
  22804. +
  22805. + err = vsc7385_upload_ucode(vsc);
  22806. + if (err)
  22807. + goto err_drvdata;
  22808. +
  22809. + err = vsc7385_setup(vsc);
  22810. + if (err)
  22811. + goto err_drvdata;
  22812. +
  22813. + return 0;
  22814. +
  22815. +err_drvdata:
  22816. + dev_set_drvdata(&spi->dev, NULL);
  22817. + kfree(vsc);
  22818. + return err;
  22819. +}
  22820. +
  22821. +static int __devexit vsc7385_remove(struct spi_device *spi)
  22822. +{
  22823. + struct vsc7385_data *vsc;
  22824. +
  22825. + vsc = dev_get_drvdata(&spi->dev);
  22826. + dev_set_drvdata(&spi->dev, NULL);
  22827. + kfree(vsc);
  22828. +
  22829. + return 0;
  22830. +}
  22831. +
  22832. +static struct spi_driver vsc7385_driver = {
  22833. + .driver = {
  22834. + .name = DRV_NAME,
  22835. + .bus = &spi_bus_type,
  22836. + .owner = THIS_MODULE,
  22837. + },
  22838. + .probe = vsc7385_probe,
  22839. + .remove = __devexit_p(vsc7385_remove),
  22840. +};
  22841. +
  22842. +static int __init vsc7385_init(void)
  22843. +{
  22844. + return spi_register_driver(&vsc7385_driver);
  22845. +}
  22846. +module_init(vsc7385_init);
  22847. +
  22848. +static void __exit vsc7385_exit(void)
  22849. +{
  22850. + spi_unregister_driver(&vsc7385_driver);
  22851. +}
  22852. +module_exit(vsc7385_exit);
  22853. +
  22854. +MODULE_DESCRIPTION(DRV_DESC);
  22855. +MODULE_VERSION(DRV_VERSION);
  22856. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  22857. +MODULE_LICENSE("GPL v2");
  22858. +
  22859. diff -Nur linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c linux-2.6.39/drivers/tty/serial/ar933x_uart.c
  22860. --- linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c 1970-01-01 01:00:00.000000000 +0100
  22861. +++ linux-2.6.39/drivers/tty/serial/ar933x_uart.c 2011-08-24 18:17:24.000000000 +0200
  22862. @@ -0,0 +1,688 @@
  22863. +/*
  22864. + * Atheros AR933X SoC built-in UART driver
  22865. + *
  22866. + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
  22867. + *
  22868. + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
  22869. + *
  22870. + * This program is free software; you can redistribute it and/or modify it
  22871. + * under the terms of the GNU General Public License version 2 as published
  22872. + * by the Free Software Foundation.
  22873. + */
  22874. +
  22875. +#include <linux/module.h>
  22876. +#include <linux/ioport.h>
  22877. +#include <linux/init.h>
  22878. +#include <linux/console.h>
  22879. +#include <linux/sysrq.h>
  22880. +#include <linux/delay.h>
  22881. +#include <linux/platform_device.h>
  22882. +#include <linux/tty.h>
  22883. +#include <linux/tty_flip.h>
  22884. +#include <linux/serial_core.h>
  22885. +#include <linux/serial.h>
  22886. +#include <linux/slab.h>
  22887. +#include <linux/io.h>
  22888. +#include <linux/irq.h>
  22889. +
  22890. +#include <asm/mach-ar71xx/ar933x_uart.h>
  22891. +#include <asm/mach-ar71xx/ar933x_uart_platform.h>
  22892. +
  22893. +#define DRIVER_NAME "ar933x-uart"
  22894. +
  22895. +#define AR933X_DUMMY_STATUS_RD 0x01
  22896. +
  22897. +static struct uart_driver ar933x_uart_driver;
  22898. +
  22899. +struct ar933x_uart_port {
  22900. + struct uart_port port;
  22901. + unsigned int ier; /* shadow Interrupt Enable Register */
  22902. +};
  22903. +
  22904. +static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
  22905. + int offset)
  22906. +{
  22907. + return readl(up->port.membase + offset);
  22908. +}
  22909. +
  22910. +static inline void ar933x_uart_write(struct ar933x_uart_port *up,
  22911. + int offset, unsigned int value)
  22912. +{
  22913. + writel(value, up->port.membase + offset);
  22914. +}
  22915. +
  22916. +static inline void ar933x_uart_rmw(struct ar933x_uart_port *up,
  22917. + unsigned int offset,
  22918. + unsigned int mask,
  22919. + unsigned int val)
  22920. +{
  22921. + unsigned int t;
  22922. +
  22923. + t = ar933x_uart_read(up, offset);
  22924. + t &= ~mask;
  22925. + t |= val;
  22926. + ar933x_uart_write(up, offset, t);
  22927. +}
  22928. +
  22929. +static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up,
  22930. + unsigned int offset,
  22931. + unsigned int val)
  22932. +{
  22933. + ar933x_uart_rmw(up, offset, 0, val);
  22934. +}
  22935. +
  22936. +static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up,
  22937. + unsigned int offset,
  22938. + unsigned int val)
  22939. +{
  22940. + ar933x_uart_rmw(up, offset, val, 0);
  22941. +}
  22942. +
  22943. +static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up)
  22944. +{
  22945. + up->ier |= AR933X_UART_INT_TX_EMPTY;
  22946. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  22947. +}
  22948. +
  22949. +static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
  22950. +{
  22951. + up->ier &= ~AR933X_UART_INT_TX_EMPTY;
  22952. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  22953. +}
  22954. +
  22955. +static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
  22956. +{
  22957. + unsigned int rdata;
  22958. +
  22959. + rdata = ch & AR933X_UART_DATA_TX_RX_MASK;
  22960. + rdata |= AR933X_UART_DATA_TX_CSR;
  22961. + ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata);
  22962. +}
  22963. +
  22964. +static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
  22965. +{
  22966. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  22967. + unsigned long flags;
  22968. + unsigned int rdata;
  22969. +
  22970. + spin_lock_irqsave(&up->port.lock, flags);
  22971. + rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
  22972. + spin_unlock_irqrestore(&up->port.lock, flags);
  22973. +
  22974. + return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT;
  22975. +}
  22976. +
  22977. +static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
  22978. +{
  22979. + return TIOCM_CAR;
  22980. +}
  22981. +
  22982. +static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
  22983. +{
  22984. +}
  22985. +
  22986. +static void ar933x_uart_start_tx(struct uart_port *port)
  22987. +{
  22988. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  22989. +
  22990. + ar933x_uart_start_tx_interrupt(up);
  22991. +}
  22992. +
  22993. +static void ar933x_uart_stop_tx(struct uart_port *port)
  22994. +{
  22995. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  22996. +
  22997. + ar933x_uart_stop_tx_interrupt(up);
  22998. +}
  22999. +
  23000. +static void ar933x_uart_stop_rx(struct uart_port *port)
  23001. +{
  23002. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23003. +
  23004. + up->ier &= ~AR933X_UART_INT_RX_VALID;
  23005. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  23006. +}
  23007. +
  23008. +static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
  23009. +{
  23010. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23011. + unsigned long flags;
  23012. +
  23013. + spin_lock_irqsave(&up->port.lock, flags);
  23014. + if (break_state == -1)
  23015. + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
  23016. + AR933X_UART_CS_TX_BREAK);
  23017. + else
  23018. + ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
  23019. + AR933X_UART_CS_TX_BREAK);
  23020. + spin_unlock_irqrestore(&up->port.lock, flags);
  23021. +}
  23022. +
  23023. +static void ar933x_uart_enable_ms(struct uart_port *port)
  23024. +{
  23025. +}
  23026. +
  23027. +static void ar933x_uart_set_termios(struct uart_port *port,
  23028. + struct ktermios *new,
  23029. + struct ktermios *old)
  23030. +{
  23031. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23032. + unsigned int cs;
  23033. + unsigned long flags;
  23034. + unsigned int baud, scale;
  23035. +
  23036. + /* Only CS8 is supported */
  23037. + new->c_cflag &= ~CSIZE;
  23038. + new->c_cflag |= CS8;
  23039. +
  23040. + /* Only one stop bit is supported */
  23041. + new->c_cflag &= ~CSTOPB;
  23042. +
  23043. + cs = 0;
  23044. + if (new->c_cflag & PARENB) {
  23045. + if (!(new->c_cflag & PARODD))
  23046. + cs |= AR933X_UART_CS_PARITY_EVEN;
  23047. + else
  23048. + cs |= AR933X_UART_CS_PARITY_ODD;
  23049. + } else {
  23050. + cs |= AR933X_UART_CS_PARITY_NONE;
  23051. + }
  23052. +
  23053. + /* Mark/space parity is not supported */
  23054. + new->c_cflag &= ~CMSPAR;
  23055. +
  23056. + baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
  23057. + scale = (port->uartclk / (16 * baud)) - 1;
  23058. +
  23059. + /*
  23060. + * Ok, we're now changing the port state. Do it with
  23061. + * interrupts disabled.
  23062. + */
  23063. + spin_lock_irqsave(&up->port.lock, flags);
  23064. +
  23065. + /* Update the per-port timeout. */
  23066. + uart_update_timeout(port, new->c_cflag, baud);
  23067. +
  23068. + up->port.ignore_status_mask = 0;
  23069. +
  23070. + /* ignore all characters if CREAD is not set */
  23071. + if ((new->c_cflag & CREAD) == 0)
  23072. + up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
  23073. +
  23074. + ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
  23075. + scale << AR933X_UART_CLOCK_SCALE_S | 8192);
  23076. +
  23077. + /* setup configuration register */
  23078. + ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
  23079. +
  23080. + /* enable host interrupt */
  23081. + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
  23082. + AR933X_UART_CS_HOST_INT_EN);
  23083. +
  23084. + spin_unlock_irqrestore(&up->port.lock, flags);
  23085. +
  23086. + if (tty_termios_baud_rate(new))
  23087. + tty_termios_encode_baud_rate(new, baud, baud);
  23088. +}
  23089. +
  23090. +static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
  23091. +{
  23092. + struct tty_struct *tty;
  23093. + int max_count = 256;
  23094. +
  23095. + tty = tty_port_tty_get(&up->port.state->port);
  23096. + do {
  23097. + unsigned int rdata;
  23098. + unsigned char ch;
  23099. +
  23100. + rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
  23101. + if ((rdata & AR933X_UART_DATA_RX_CSR) == 0)
  23102. + break;
  23103. +
  23104. + /* remove the character from the FIFO */
  23105. + ar933x_uart_write(up, AR933X_UART_DATA_REG,
  23106. + AR933X_UART_DATA_RX_CSR);
  23107. +
  23108. + if (!tty) {
  23109. + /* discard the data if no tty available */
  23110. + continue;
  23111. + }
  23112. +
  23113. + up->port.icount.rx++;
  23114. + ch = rdata & AR933X_UART_DATA_TX_RX_MASK;
  23115. +
  23116. + if (uart_handle_sysrq_char(&up->port, ch))
  23117. + continue;
  23118. +
  23119. + if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0)
  23120. + tty_insert_flip_char(tty, ch, TTY_NORMAL);
  23121. + } while (max_count-- > 0);
  23122. +
  23123. + if (tty) {
  23124. + tty_flip_buffer_push(tty);
  23125. + tty_kref_put(tty);
  23126. + }
  23127. +}
  23128. +
  23129. +static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
  23130. +{
  23131. + struct circ_buf *xmit = &up->port.state->xmit;
  23132. + int count;
  23133. +
  23134. + if (uart_tx_stopped(&up->port))
  23135. + return;
  23136. +
  23137. + count = up->port.fifosize;
  23138. + do {
  23139. + unsigned int rdata;
  23140. +
  23141. + rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
  23142. + if ((rdata & AR933X_UART_DATA_TX_CSR) == 0)
  23143. + break;
  23144. +
  23145. + if (up->port.x_char) {
  23146. + ar933x_uart_putc(up, up->port.x_char);
  23147. + up->port.icount.tx++;
  23148. + up->port.x_char = 0;
  23149. + continue;
  23150. + }
  23151. +
  23152. + if (uart_circ_empty(xmit))
  23153. + break;
  23154. +
  23155. + ar933x_uart_putc(up, xmit->buf[xmit->tail]);
  23156. +
  23157. + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
  23158. + up->port.icount.tx++;
  23159. + } while (--count > 0);
  23160. +
  23161. + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
  23162. + uart_write_wakeup(&up->port);
  23163. +
  23164. + if (!uart_circ_empty(xmit))
  23165. + ar933x_uart_start_tx_interrupt(up);
  23166. +}
  23167. +
  23168. +static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
  23169. +{
  23170. + struct ar933x_uart_port *up = dev_id;
  23171. + unsigned int status;
  23172. +
  23173. + status = ar933x_uart_read(up, AR933X_UART_CS_REG);
  23174. + if ((status & AR933X_UART_CS_HOST_INT) == 0)
  23175. + return IRQ_NONE;
  23176. +
  23177. + spin_lock(&up->port.lock);
  23178. +
  23179. + status = ar933x_uart_read(up, AR933X_UART_INT_REG);
  23180. + status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
  23181. +
  23182. + if (status & AR933X_UART_INT_RX_VALID) {
  23183. + ar933x_uart_write(up, AR933X_UART_INT_REG,
  23184. + AR933X_UART_INT_RX_VALID);
  23185. + ar933x_uart_rx_chars(up);
  23186. + }
  23187. +
  23188. + if (status & AR933X_UART_INT_TX_EMPTY) {
  23189. + ar933x_uart_write(up, AR933X_UART_INT_REG,
  23190. + AR933X_UART_INT_TX_EMPTY);
  23191. + ar933x_uart_stop_tx_interrupt(up);
  23192. + ar933x_uart_tx_chars(up);
  23193. + }
  23194. +
  23195. + spin_unlock(&up->port.lock);
  23196. +
  23197. + return IRQ_HANDLED;
  23198. +}
  23199. +
  23200. +static int ar933x_uart_startup(struct uart_port *port)
  23201. +{
  23202. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23203. + unsigned long flags;
  23204. + int ret;
  23205. +
  23206. + ret = request_irq(up->port.irq, ar933x_uart_interrupt,
  23207. + up->port.irqflags, dev_name(up->port.dev), up);
  23208. + if (ret)
  23209. + return ret;
  23210. +
  23211. + spin_lock_irqsave(&up->port.lock, flags);
  23212. +
  23213. + /* Enable HOST interrupts */
  23214. + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
  23215. + AR933X_UART_CS_HOST_INT_EN);
  23216. +
  23217. + /* Enable RX interrupts */
  23218. + up->ier = AR933X_UART_INT_RX_VALID;
  23219. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  23220. +
  23221. + spin_unlock_irqrestore(&up->port.lock, flags);
  23222. +
  23223. + return 0;
  23224. +}
  23225. +
  23226. +static void ar933x_uart_shutdown(struct uart_port *port)
  23227. +{
  23228. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23229. +
  23230. + /* Disable all interrupts */
  23231. + up->ier = 0;
  23232. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  23233. +
  23234. + /* Disable break condition */
  23235. + ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
  23236. + AR933X_UART_CS_TX_BREAK);
  23237. +
  23238. + free_irq(up->port.irq, up);
  23239. +}
  23240. +
  23241. +static const char *ar933x_uart_type(struct uart_port *port)
  23242. +{
  23243. + return (port->type == PORT_AR933X) ? "AR933X UART" : NULL;
  23244. +}
  23245. +
  23246. +static void ar933x_uart_release_port(struct uart_port *port)
  23247. +{
  23248. + /* Nothing to release ... */
  23249. +}
  23250. +
  23251. +static int ar933x_uart_request_port(struct uart_port *port)
  23252. +{
  23253. + /* UARTs always present */
  23254. + return 0;
  23255. +}
  23256. +
  23257. +static void ar933x_uart_config_port(struct uart_port *port, int flags)
  23258. +{
  23259. + if (flags & UART_CONFIG_TYPE)
  23260. + port->type = PORT_AR933X;
  23261. +}
  23262. +
  23263. +static int ar933x_uart_verify_port(struct uart_port *port,
  23264. + struct serial_struct *ser)
  23265. +{
  23266. + if (ser->type != PORT_UNKNOWN &&
  23267. + ser->type != PORT_AR933X)
  23268. + return -EINVAL;
  23269. +
  23270. + if (ser->irq < 0 || ser->irq >= NR_IRQS)
  23271. + return -EINVAL;
  23272. +
  23273. + if (ser->baud_base < 28800)
  23274. + return -EINVAL;
  23275. +
  23276. + return 0;
  23277. +}
  23278. +
  23279. +static struct uart_ops ar933x_uart_ops = {
  23280. + .tx_empty = ar933x_uart_tx_empty,
  23281. + .set_mctrl = ar933x_uart_set_mctrl,
  23282. + .get_mctrl = ar933x_uart_get_mctrl,
  23283. + .stop_tx = ar933x_uart_stop_tx,
  23284. + .start_tx = ar933x_uart_start_tx,
  23285. + .stop_rx = ar933x_uart_stop_rx,
  23286. + .enable_ms = ar933x_uart_enable_ms,
  23287. + .break_ctl = ar933x_uart_break_ctl,
  23288. + .startup = ar933x_uart_startup,
  23289. + .shutdown = ar933x_uart_shutdown,
  23290. + .set_termios = ar933x_uart_set_termios,
  23291. + .type = ar933x_uart_type,
  23292. + .release_port = ar933x_uart_release_port,
  23293. + .request_port = ar933x_uart_request_port,
  23294. + .config_port = ar933x_uart_config_port,
  23295. + .verify_port = ar933x_uart_verify_port,
  23296. +};
  23297. +
  23298. +#ifdef CONFIG_SERIAL_AR933X_CONSOLE
  23299. +
  23300. +static struct ar933x_uart_port *
  23301. +ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
  23302. +
  23303. +static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up)
  23304. +{
  23305. + unsigned int status;
  23306. + unsigned int timeout = 60000;
  23307. +
  23308. + /* Wait up to 60ms for the character(s) to be sent. */
  23309. + do {
  23310. + status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
  23311. + if (--timeout == 0)
  23312. + break;
  23313. + udelay(1);
  23314. + } while ((status & AR933X_UART_DATA_TX_CSR) == 0);
  23315. +}
  23316. +
  23317. +static void ar933x_uart_console_putchar(struct uart_port *port, int ch)
  23318. +{
  23319. + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
  23320. +
  23321. + ar933x_uart_wait_xmitr(up);
  23322. + ar933x_uart_putc(up, ch);
  23323. +}
  23324. +
  23325. +static void ar933x_uart_console_write(struct console *co, const char *s,
  23326. + unsigned int count)
  23327. +{
  23328. + struct ar933x_uart_port *up = ar933x_console_ports[co->index];
  23329. + unsigned long flags;
  23330. + unsigned int int_en;
  23331. + int locked = 1;
  23332. +
  23333. + local_irq_save(flags);
  23334. +
  23335. + if (up->port.sysrq)
  23336. + locked = 0;
  23337. + else if (oops_in_progress)
  23338. + locked = spin_trylock(&up->port.lock);
  23339. + else
  23340. + spin_lock(&up->port.lock);
  23341. +
  23342. + /*
  23343. + * First save the IER then disable the interrupts
  23344. + */
  23345. + int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
  23346. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
  23347. +
  23348. + uart_console_write(&up->port, s, count, ar933x_uart_console_putchar);
  23349. +
  23350. + /*
  23351. + * Finally, wait for transmitter to become empty
  23352. + * and restore the IER
  23353. + */
  23354. + ar933x_uart_wait_xmitr(up);
  23355. + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en);
  23356. +
  23357. + ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS);
  23358. +
  23359. + if (locked)
  23360. + spin_unlock(&up->port.lock);
  23361. +
  23362. + local_irq_restore(flags);
  23363. +}
  23364. +
  23365. +static int ar933x_uart_console_setup(struct console *co, char *options)
  23366. +{
  23367. + struct ar933x_uart_port *up;
  23368. + int baud = 115200;
  23369. + int bits = 8;
  23370. + int parity = 'n';
  23371. + int flow = 'n';
  23372. +
  23373. + if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS)
  23374. + return -EINVAL;
  23375. +
  23376. + up = ar933x_console_ports[co->index];
  23377. + if (!up)
  23378. + return -ENODEV;
  23379. +
  23380. + if (options)
  23381. + uart_parse_options(options, &baud, &parity, &bits, &flow);
  23382. +
  23383. + return uart_set_options(&up->port, co, baud, parity, bits, flow);
  23384. +}
  23385. +
  23386. +static struct console ar933x_uart_console = {
  23387. + .name = "ttyATH",
  23388. + .write = ar933x_uart_console_write,
  23389. + .device = uart_console_device,
  23390. + .setup = ar933x_uart_console_setup,
  23391. + .flags = CON_PRINTBUFFER,
  23392. + .index = -1,
  23393. + .data = &ar933x_uart_driver,
  23394. +};
  23395. +
  23396. +static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
  23397. +{
  23398. + ar933x_console_ports[up->port.line] = up;
  23399. +}
  23400. +
  23401. +#define AR933X_SERIAL_CONSOLE (&ar933x_uart_console)
  23402. +
  23403. +#else
  23404. +
  23405. +static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {}
  23406. +
  23407. +#define AR933X_SERIAL_CONSOLE NULL
  23408. +
  23409. +#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
  23410. +
  23411. +static struct uart_driver ar933x_uart_driver = {
  23412. + .owner = THIS_MODULE,
  23413. + .driver_name = DRIVER_NAME,
  23414. + .dev_name = "ttyATH",
  23415. + .nr = CONFIG_SERIAL_AR933X_NR_UARTS,
  23416. + .cons = AR933X_SERIAL_CONSOLE,
  23417. +};
  23418. +
  23419. +static int __devinit ar933x_uart_probe(struct platform_device *pdev)
  23420. +{
  23421. + struct ar933x_uart_platform_data *pdata;
  23422. + struct ar933x_uart_port *up;
  23423. + struct uart_port *port;
  23424. + struct resource *mem_res;
  23425. + struct resource *irq_res;
  23426. + int id;
  23427. + int ret;
  23428. +
  23429. + pdata = pdev->dev.platform_data;
  23430. + if (!pdata)
  23431. + return -EINVAL;
  23432. +
  23433. + id = pdev->id;
  23434. + if (id == -1)
  23435. + id = 0;
  23436. +
  23437. + if (id > CONFIG_SERIAL_AR933X_NR_UARTS)
  23438. + return -EINVAL;
  23439. +
  23440. + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  23441. + if (!mem_res) {
  23442. + dev_err(&pdev->dev, "no MEM resource\n");
  23443. + return -EINVAL;
  23444. + }
  23445. +
  23446. + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  23447. + if (!irq_res) {
  23448. + dev_err(&pdev->dev, "no IRQ resource\n");
  23449. + return -EINVAL;
  23450. + }
  23451. +
  23452. + up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL);
  23453. + if (!up)
  23454. + return -ENOMEM;
  23455. +
  23456. + port = &up->port;
  23457. + port->mapbase = mem_res->start;
  23458. +
  23459. + port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE);
  23460. + if (!port->membase) {
  23461. + ret = -ENOMEM;
  23462. + goto err_free_up;
  23463. + }
  23464. +
  23465. + port->line = id;
  23466. + port->irq = irq_res->start;
  23467. + port->dev = &pdev->dev;
  23468. + port->type = PORT_AR933X;
  23469. + port->iotype = UPIO_MEM32;
  23470. + port->uartclk = pdata->uartclk;
  23471. +
  23472. + port->regshift = 2;
  23473. + port->fifosize = AR933X_UART_FIFO_SIZE;
  23474. + port->ops = &ar933x_uart_ops;
  23475. +
  23476. + ar933x_uart_add_console_port(up);
  23477. +
  23478. + ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
  23479. + if (ret)
  23480. + goto err_unmap;
  23481. +
  23482. + platform_set_drvdata(pdev, up);
  23483. + return 0;
  23484. +
  23485. +err_unmap:
  23486. + iounmap(up->port.membase);
  23487. +err_free_up:
  23488. + kfree(up);
  23489. + return ret;
  23490. +}
  23491. +
  23492. +static int __devexit ar933x_uart_remove(struct platform_device *pdev)
  23493. +{
  23494. + struct ar933x_uart_port *up;
  23495. +
  23496. + up = platform_get_drvdata(pdev);
  23497. + platform_set_drvdata(pdev, NULL);
  23498. +
  23499. + if (up) {
  23500. + uart_remove_one_port(&ar933x_uart_driver, &up->port);
  23501. + iounmap(up->port.membase);
  23502. + kfree(up);
  23503. + }
  23504. +
  23505. + return 0;
  23506. +}
  23507. +
  23508. +static struct platform_driver ar933x_uart_platform_driver = {
  23509. + .probe = ar933x_uart_probe,
  23510. + .remove = __devexit_p(ar933x_uart_remove),
  23511. + .driver = {
  23512. + .name = DRIVER_NAME,
  23513. + .owner = THIS_MODULE,
  23514. + },
  23515. +};
  23516. +
  23517. +static int __init ar933x_uart_init(void)
  23518. +{
  23519. + int ret;
  23520. +
  23521. + ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS;
  23522. + ret = uart_register_driver(&ar933x_uart_driver);
  23523. + if (ret)
  23524. + goto err_out;
  23525. +
  23526. + ret = platform_driver_register(&ar933x_uart_platform_driver);
  23527. + if (ret)
  23528. + goto err_unregister_uart_driver;
  23529. +
  23530. + return 0;
  23531. +
  23532. +err_unregister_uart_driver:
  23533. + uart_unregister_driver(&ar933x_uart_driver);
  23534. +err_out:
  23535. + return ret;
  23536. +}
  23537. +
  23538. +static void __exit ar933x_uart_exit(void)
  23539. +{
  23540. + platform_driver_unregister(&ar933x_uart_platform_driver);
  23541. + uart_unregister_driver(&ar933x_uart_driver);
  23542. +}
  23543. +
  23544. +module_init(ar933x_uart_init);
  23545. +module_exit(ar933x_uart_exit);
  23546. +
  23547. +MODULE_DESCRIPTION("Atheros AR933X UART driver");
  23548. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  23549. +MODULE_LICENSE("GPL v2");
  23550. +MODULE_ALIAS("platform:" DRIVER_NAME);
  23551. diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig
  23552. --- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200
  23553. +++ linux-2.6.39/drivers/usb/host/Kconfig 2011-08-24 18:17:24.000000000 +0200
  23554. @@ -129,6 +129,13 @@
  23555. config USB_FSL_MPH_DR_OF
  23556. tristate
  23557. +config USB_EHCI_AR71XX
  23558. + bool "USB EHCI support for AR71xx"
  23559. + depends on USB_EHCI_HCD && ATHEROS_AR71XX
  23560. + default y
  23561. + help
  23562. + Support for Atheros AR71xx built-in EHCI controller
  23563. +
  23564. config USB_EHCI_FSL
  23565. bool "Support for Freescale on-chip EHCI USB controller"
  23566. depends on USB_EHCI_HCD && FSL_SOC
  23567. @@ -287,6 +294,13 @@
  23568. Enables support for the on-chip OHCI controller on
  23569. OMAP3 and later chips.
  23570. +config USB_OHCI_AR71XX
  23571. + bool "USB OHCI support for Atheros AR71xx"
  23572. + depends on USB_OHCI_HCD && ATHEROS_AR71XX
  23573. + default y
  23574. + help
  23575. + Support for Atheros AR71xx built-in OHCI controller
  23576. +
  23577. config USB_OHCI_HCD_PPC_SOC
  23578. bool "OHCI support for on-chip PPC USB controller"
  23579. depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
  23580. diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/usb/host/ehci-ar71xx.c
  23581. --- linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  23582. +++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200
  23583. @@ -0,0 +1,242 @@
  23584. +/*
  23585. + * Bus Glue for Atheros AR71xx built-in EHCI controller.
  23586. + *
  23587. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  23588. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  23589. + *
  23590. + * Parts of this file are based on Atheros' 2.6.15 BSP
  23591. + * Copyright (C) 2007 Atheros Communications, Inc.
  23592. + *
  23593. + * This program is free software; you can redistribute it and/or modify it
  23594. + * under the terms of the GNU General Public License version 2 as published
  23595. + * by the Free Software Foundation.
  23596. + */
  23597. +
  23598. +#include <linux/platform_device.h>
  23599. +#include <linux/delay.h>
  23600. +
  23601. +#include <asm/mach-ar71xx/platform.h>
  23602. +
  23603. +extern int usb_disabled(void);
  23604. +
  23605. +static int ehci_ar71xx_init(struct usb_hcd *hcd)
  23606. +{
  23607. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  23608. + int ret;
  23609. +
  23610. + ehci->caps = hcd->regs;
  23611. + ehci->regs = hcd->regs +
  23612. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  23613. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  23614. +
  23615. + ehci->sbrn = 0x20;
  23616. + ehci->has_synopsys_hc_bug = 1;
  23617. +
  23618. + ehci_reset(ehci);
  23619. +
  23620. + ret = ehci_init(hcd);
  23621. + if (ret)
  23622. + return ret;
  23623. +
  23624. + ehci_port_power(ehci, 0);
  23625. +
  23626. + return 0;
  23627. +}
  23628. +
  23629. +static int ehci_ar91xx_init(struct usb_hcd *hcd)
  23630. +{
  23631. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  23632. + int ret;
  23633. +
  23634. + ehci->caps = hcd->regs + 0x100;
  23635. + ehci->regs = hcd->regs + 0x100 +
  23636. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  23637. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  23638. +
  23639. + hcd->has_tt = 1;
  23640. + ehci->sbrn = 0x20;
  23641. +
  23642. + ehci_reset(ehci);
  23643. +
  23644. + ret = ehci_init(hcd);
  23645. + if (ret)
  23646. + return ret;
  23647. +
  23648. + ehci_port_power(ehci, 0);
  23649. +
  23650. + return 0;
  23651. +}
  23652. +
  23653. +static int ehci_ar71xx_probe(const struct hc_driver *driver,
  23654. + struct usb_hcd **hcd_out,
  23655. + struct platform_device *pdev)
  23656. +{
  23657. + struct usb_hcd *hcd;
  23658. + struct resource *res;
  23659. + int irq;
  23660. + int ret;
  23661. +
  23662. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  23663. + if (!res) {
  23664. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  23665. + dev_name(&pdev->dev));
  23666. + return -ENODEV;
  23667. + }
  23668. + irq = res->start;
  23669. +
  23670. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  23671. + if (!res) {
  23672. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  23673. + dev_name(&pdev->dev));
  23674. + return -ENODEV;
  23675. + }
  23676. +
  23677. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  23678. + if (!hcd)
  23679. + return -ENOMEM;
  23680. +
  23681. + hcd->rsrc_start = res->start;
  23682. + hcd->rsrc_len = res->end - res->start + 1;
  23683. +
  23684. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  23685. + dev_dbg(&pdev->dev, "controller already in use\n");
  23686. + ret = -EBUSY;
  23687. + goto err_put_hcd;
  23688. + }
  23689. +
  23690. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  23691. + if (!hcd->regs) {
  23692. + dev_dbg(&pdev->dev, "error mapping memory\n");
  23693. + ret = -EFAULT;
  23694. + goto err_release_region;
  23695. + }
  23696. +
  23697. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  23698. + if (ret)
  23699. + goto err_iounmap;
  23700. +
  23701. + return 0;
  23702. +
  23703. +err_iounmap:
  23704. + iounmap(hcd->regs);
  23705. +
  23706. +err_release_region:
  23707. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  23708. +err_put_hcd:
  23709. + usb_put_hcd(hcd);
  23710. + return ret;
  23711. +}
  23712. +
  23713. +static void ehci_ar71xx_remove(struct usb_hcd *hcd,
  23714. + struct platform_device *pdev)
  23715. +{
  23716. + usb_remove_hcd(hcd);
  23717. + iounmap(hcd->regs);
  23718. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  23719. + usb_put_hcd(hcd);
  23720. +}
  23721. +
  23722. +static const struct hc_driver ehci_ar71xx_hc_driver = {
  23723. + .description = hcd_name,
  23724. + .product_desc = "Atheros AR71xx built-in EHCI controller",
  23725. + .hcd_priv_size = sizeof(struct ehci_hcd),
  23726. +
  23727. + .irq = ehci_irq,
  23728. + .flags = HCD_MEMORY | HCD_USB2,
  23729. +
  23730. + .reset = ehci_ar71xx_init,
  23731. + .start = ehci_run,
  23732. + .stop = ehci_stop,
  23733. + .shutdown = ehci_shutdown,
  23734. +
  23735. + .urb_enqueue = ehci_urb_enqueue,
  23736. + .urb_dequeue = ehci_urb_dequeue,
  23737. + .endpoint_disable = ehci_endpoint_disable,
  23738. + .endpoint_reset = ehci_endpoint_reset,
  23739. +
  23740. + .get_frame_number = ehci_get_frame,
  23741. +
  23742. + .hub_status_data = ehci_hub_status_data,
  23743. + .hub_control = ehci_hub_control,
  23744. +#ifdef CONFIG_PM
  23745. + .hub_suspend = ehci_hub_suspend,
  23746. + .hub_resume = ehci_hub_resume,
  23747. +#endif
  23748. + .relinquish_port = ehci_relinquish_port,
  23749. + .port_handed_over = ehci_port_handed_over,
  23750. +
  23751. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  23752. +};
  23753. +
  23754. +static const struct hc_driver ehci_ar91xx_hc_driver = {
  23755. + .description = hcd_name,
  23756. + .product_desc = "Atheros AR91xx built-in EHCI controller",
  23757. + .hcd_priv_size = sizeof(struct ehci_hcd),
  23758. + .irq = ehci_irq,
  23759. + .flags = HCD_MEMORY | HCD_USB2,
  23760. +
  23761. + .reset = ehci_ar91xx_init,
  23762. + .start = ehci_run,
  23763. + .stop = ehci_stop,
  23764. + .shutdown = ehci_shutdown,
  23765. +
  23766. + .urb_enqueue = ehci_urb_enqueue,
  23767. + .urb_dequeue = ehci_urb_dequeue,
  23768. + .endpoint_disable = ehci_endpoint_disable,
  23769. + .endpoint_reset = ehci_endpoint_reset,
  23770. +
  23771. + .get_frame_number = ehci_get_frame,
  23772. +
  23773. + .hub_status_data = ehci_hub_status_data,
  23774. + .hub_control = ehci_hub_control,
  23775. +#ifdef CONFIG_PM
  23776. + .hub_suspend = ehci_hub_suspend,
  23777. + .hub_resume = ehci_hub_resume,
  23778. +#endif
  23779. + .relinquish_port = ehci_relinquish_port,
  23780. + .port_handed_over = ehci_port_handed_over,
  23781. +
  23782. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  23783. +};
  23784. +
  23785. +static int ehci_ar71xx_driver_probe(struct platform_device *pdev)
  23786. +{
  23787. + struct ar71xx_ehci_platform_data *pdata;
  23788. + struct usb_hcd *hcd = NULL;
  23789. + int ret;
  23790. +
  23791. + if (usb_disabled())
  23792. + return -ENODEV;
  23793. +
  23794. + pdata = pdev->dev.platform_data;
  23795. + if (!pdata) {
  23796. + dev_err(&pdev->dev, "no platform data specified for %s\n",
  23797. + dev_name(&pdev->dev));
  23798. + return -ENODEV;
  23799. + }
  23800. +
  23801. + if (pdata->is_ar91xx)
  23802. + ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev);
  23803. + else
  23804. + ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev);
  23805. +
  23806. + return ret;
  23807. +}
  23808. +
  23809. +static int ehci_ar71xx_driver_remove(struct platform_device *pdev)
  23810. +{
  23811. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  23812. +
  23813. + ehci_ar71xx_remove(hcd, pdev);
  23814. + return 0;
  23815. +}
  23816. +
  23817. +MODULE_ALIAS("platform:ar71xx-ehci");
  23818. +
  23819. +static struct platform_driver ehci_ar71xx_driver = {
  23820. + .probe = ehci_ar71xx_driver_probe,
  23821. + .remove = ehci_ar71xx_driver_remove,
  23822. + .driver = {
  23823. + .name = "ar71xx-ehci",
  23824. + }
  23825. +};
  23826. diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb/host/ehci-hcd.c
  23827. --- linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c 2011-05-19 06:06:34.000000000 +0200
  23828. +++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-08-24 18:17:24.000000000 +0200
  23829. @@ -1265,6 +1265,11 @@
  23830. #define PLATFORM_DRIVER tegra_ehci_driver
  23831. #endif
  23832. +#ifdef CONFIG_USB_EHCI_AR71XX
  23833. +#include "ehci-ar71xx.c"
  23834. +#define PLATFORM_DRIVER ehci_ar71xx_driver
  23835. +#endif
  23836. +
  23837. #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
  23838. !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
  23839. !defined(XILINX_OF_PLATFORM_DRIVER)
  23840. diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/usb/host/ohci-ar71xx.c
  23841. --- linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  23842. +++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200
  23843. @@ -0,0 +1,165 @@
  23844. +/*
  23845. + * OHCI HCD (Host Controller Driver) for USB.
  23846. + *
  23847. + * Bus Glue for Atheros AR71xx built-in OHCI controller.
  23848. + *
  23849. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  23850. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  23851. + *
  23852. + * Parts of this file are based on Atheros' 2.6.15 BSP
  23853. + * Copyright (C) 2007 Atheros Communications, Inc.
  23854. + *
  23855. + * This program is free software; you can redistribute it and/or modify it
  23856. + * under the terms of the GNU General Public License version 2 as published
  23857. + * by the Free Software Foundation.
  23858. + */
  23859. +
  23860. +#include <linux/platform_device.h>
  23861. +#include <linux/delay.h>
  23862. +
  23863. +extern int usb_disabled(void);
  23864. +
  23865. +static int usb_hcd_ar71xx_probe(const struct hc_driver *driver,
  23866. + struct platform_device *pdev)
  23867. +{
  23868. + struct usb_hcd *hcd;
  23869. + struct resource *res;
  23870. + int irq;
  23871. + int ret;
  23872. +
  23873. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  23874. + if (!res) {
  23875. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  23876. + dev_name(&pdev->dev));
  23877. + return -ENODEV;
  23878. + }
  23879. + irq = res->start;
  23880. +
  23881. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  23882. + if (!hcd)
  23883. + return -ENOMEM;
  23884. +
  23885. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  23886. + if (!res) {
  23887. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  23888. + dev_name(&pdev->dev));
  23889. + ret = -ENODEV;
  23890. + goto err_put_hcd;
  23891. + }
  23892. + hcd->rsrc_start = res->start;
  23893. + hcd->rsrc_len = res->end - res->start + 1;
  23894. +
  23895. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  23896. + dev_dbg(&pdev->dev, "controller already in use\n");
  23897. + ret = -EBUSY;
  23898. + goto err_put_hcd;
  23899. + }
  23900. +
  23901. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  23902. + if (!hcd->regs) {
  23903. + dev_dbg(&pdev->dev, "error mapping memory\n");
  23904. + ret = -EFAULT;
  23905. + goto err_release_region;
  23906. + }
  23907. +
  23908. + ohci_hcd_init(hcd_to_ohci(hcd));
  23909. +
  23910. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  23911. + if (ret)
  23912. + goto err_stop_hcd;
  23913. +
  23914. + return 0;
  23915. +
  23916. +err_stop_hcd:
  23917. + iounmap(hcd->regs);
  23918. +err_release_region:
  23919. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  23920. +err_put_hcd:
  23921. + usb_put_hcd(hcd);
  23922. + return ret;
  23923. +}
  23924. +
  23925. +void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  23926. +{
  23927. + usb_remove_hcd(hcd);
  23928. + iounmap(hcd->regs);
  23929. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  23930. + usb_put_hcd(hcd);
  23931. +}
  23932. +
  23933. +static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd)
  23934. +{
  23935. + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  23936. + int ret;
  23937. +
  23938. + ret = ohci_init(ohci);
  23939. + if (ret < 0)
  23940. + return ret;
  23941. +
  23942. + ret = ohci_run(ohci);
  23943. + if (ret < 0)
  23944. + goto err;
  23945. +
  23946. + return 0;
  23947. +
  23948. +err:
  23949. + ohci_stop(hcd);
  23950. + return ret;
  23951. +}
  23952. +
  23953. +static const struct hc_driver ohci_ar71xx_hc_driver = {
  23954. + .description = hcd_name,
  23955. + .product_desc = "Atheros AR71xx built-in OHCI controller",
  23956. + .hcd_priv_size = sizeof(struct ohci_hcd),
  23957. +
  23958. + .irq = ohci_irq,
  23959. + .flags = HCD_USB11 | HCD_MEMORY,
  23960. +
  23961. + .start = ohci_ar71xx_start,
  23962. + .stop = ohci_stop,
  23963. + .shutdown = ohci_shutdown,
  23964. +
  23965. + .urb_enqueue = ohci_urb_enqueue,
  23966. + .urb_dequeue = ohci_urb_dequeue,
  23967. + .endpoint_disable = ohci_endpoint_disable,
  23968. +
  23969. + /*
  23970. + * scheduling support
  23971. + */
  23972. + .get_frame_number = ohci_get_frame,
  23973. +
  23974. + /*
  23975. + * root hub support
  23976. + */
  23977. + .hub_status_data = ohci_hub_status_data,
  23978. + .hub_control = ohci_hub_control,
  23979. + .start_port_reset = ohci_start_port_reset,
  23980. +};
  23981. +
  23982. +static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev)
  23983. +{
  23984. + if (usb_disabled())
  23985. + return -ENODEV;
  23986. +
  23987. + return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev);
  23988. +}
  23989. +
  23990. +static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev)
  23991. +{
  23992. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  23993. +
  23994. + usb_hcd_ar71xx_remove(hcd, pdev);
  23995. + return 0;
  23996. +}
  23997. +
  23998. +MODULE_ALIAS("platform:ar71xx-ohci");
  23999. +
  24000. +static struct platform_driver ohci_hcd_ar71xx_driver = {
  24001. + .probe = ohci_hcd_ar71xx_drv_probe,
  24002. + .remove = ohci_hcd_ar71xx_drv_remove,
  24003. + .shutdown = usb_hcd_platform_shutdown,
  24004. + .driver = {
  24005. + .name = "ar71xx-ohci",
  24006. + .owner = THIS_MODULE,
  24007. + },
  24008. +};
  24009. diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb/host/ohci-hcd.c
  24010. --- linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c 2011-05-19 06:06:34.000000000 +0200
  24011. +++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-08-24 18:17:24.000000000 +0200
  24012. @@ -1105,6 +1105,11 @@
  24013. #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
  24014. #endif
  24015. +#ifdef CONFIG_USB_OHCI_AR71XX
  24016. +#include "ohci-ar71xx.c"
  24017. +#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
  24018. +#endif
  24019. +
  24020. #if !defined(PCI_DRIVER) && \
  24021. !defined(PLATFORM_DRIVER) && \
  24022. !defined(OMAP1_PLATFORM_DRIVER) && \
  24023. diff -Nur linux-2.6.39.orig/drivers/watchdog/Kconfig linux-2.6.39/drivers/watchdog/Kconfig
  24024. --- linux-2.6.39.orig/drivers/watchdog/Kconfig 2011-05-19 06:06:34.000000000 +0200
  24025. +++ linux-2.6.39/drivers/watchdog/Kconfig 2011-08-24 18:17:24.000000000 +0200
  24026. @@ -990,6 +990,13 @@
  24027. To compile this driver as a loadable module, choose M here.
  24028. The module will be called bcm63xx_wdt.
  24029. +config AR71XX_WDT
  24030. + tristate "Atheros AR71xx Watchdog Timer"
  24031. + depends on ATHEROS_AR71XX
  24032. + help
  24033. + Hardware driver for the built-in watchdog timer on the Atheros
  24034. + AR71xx SoCs.
  24035. +
  24036. # PARISC Architecture
  24037. # POWERPC Architecture
  24038. diff -Nur linux-2.6.39.orig/drivers/watchdog/Makefile linux-2.6.39/drivers/watchdog/Makefile
  24039. --- linux-2.6.39.orig/drivers/watchdog/Makefile 2011-05-19 06:06:34.000000000 +0200
  24040. +++ linux-2.6.39/drivers/watchdog/Makefile 2011-08-24 18:17:24.000000000 +0200
  24041. @@ -119,6 +119,7 @@
  24042. obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
  24043. obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
  24044. obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
  24045. +obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
  24046. obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
  24047. obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
  24048. obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
  24049. diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/watchdog/ar71xx_wdt.c
  24050. --- linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100
  24051. +++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-08-24 18:17:24.000000000 +0200
  24052. @@ -0,0 +1,299 @@
  24053. +/*
  24054. + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer.
  24055. + *
  24056. + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  24057. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  24058. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  24059. + *
  24060. + * Parts of this file are based on Atheros 2.6.31 BSP
  24061. + *
  24062. + * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
  24063. + * Author: Deepak Saxena <dsaxena@plexity.net>
  24064. + * Copyright 2004 (c) MontaVista, Software, Inc.
  24065. + *
  24066. + * which again was based on sa1100 driver,
  24067. + * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
  24068. + *
  24069. + * This program is free software; you can redistribute it and/or modify it
  24070. + * under the terms of the GNU General Public License version 2 as published
  24071. + * by the Free Software Foundation.
  24072. + *
  24073. + */
  24074. +
  24075. +#include <linux/bitops.h>
  24076. +#include <linux/errno.h>
  24077. +#include <linux/fs.h>
  24078. +#include <linux/init.h>
  24079. +#include <linux/kernel.h>
  24080. +#include <linux/miscdevice.h>
  24081. +#include <linux/module.h>
  24082. +#include <linux/moduleparam.h>
  24083. +#include <linux/platform_device.h>
  24084. +#include <linux/types.h>
  24085. +#include <linux/watchdog.h>
  24086. +#include <linux/delay.h>
  24087. +
  24088. +#include <asm/mach-ar71xx/ar71xx.h>
  24089. +
  24090. +#define DRV_NAME "ar71xx-wdt"
  24091. +#define DRV_DESC "Atheros AR71xx hardware watchdog driver"
  24092. +#define DRV_VERSION "0.1.0"
  24093. +
  24094. +#define WDT_TIMEOUT 15 /* seconds */
  24095. +
  24096. +static int nowayout = WATCHDOG_NOWAYOUT;
  24097. +
  24098. +#ifdef CONFIG_WATCHDOG_NOWAYOUT
  24099. +module_param(nowayout, int, 0);
  24100. +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  24101. + "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  24102. +#endif
  24103. +
  24104. +static unsigned long wdt_flags;
  24105. +
  24106. +#define WDT_FLAGS_BUSY 0
  24107. +#define WDT_FLAGS_EXPECT_CLOSE 1
  24108. +
  24109. +static int wdt_timeout = WDT_TIMEOUT;
  24110. +static int boot_status;
  24111. +static int max_timeout;
  24112. +static u32 wdt_clk_freq;
  24113. +
  24114. +static inline void ar71xx_wdt_keepalive(void)
  24115. +{
  24116. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, wdt_clk_freq * wdt_timeout);
  24117. +}
  24118. +
  24119. +static inline void ar71xx_wdt_enable(void)
  24120. +{
  24121. + printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n");
  24122. + ar71xx_wdt_keepalive();
  24123. + udelay(2);
  24124. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
  24125. +}
  24126. +
  24127. +static inline void ar71xx_wdt_disable(void)
  24128. +{
  24129. + printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n");
  24130. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
  24131. +}
  24132. +
  24133. +static int ar71xx_wdt_set_timeout(int val)
  24134. +{
  24135. + if (val < 1 || val > max_timeout)
  24136. + return -EINVAL;
  24137. +
  24138. + wdt_timeout = val;
  24139. + ar71xx_wdt_keepalive();
  24140. +
  24141. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout);
  24142. +
  24143. + return 0;
  24144. +}
  24145. +
  24146. +static int ar71xx_wdt_open(struct inode *inode, struct file *file)
  24147. +{
  24148. + if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
  24149. + return -EBUSY;
  24150. +
  24151. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  24152. +
  24153. + ar71xx_wdt_enable();
  24154. +
  24155. + return nonseekable_open(inode, file);
  24156. +}
  24157. +
  24158. +static int ar71xx_wdt_release(struct inode *inode, struct file *file)
  24159. +{
  24160. + if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) {
  24161. + ar71xx_wdt_disable();
  24162. + } else {
  24163. + printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, "
  24164. + "watchdog timer will not stop!\n");
  24165. + }
  24166. +
  24167. + clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
  24168. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  24169. +
  24170. + return 0;
  24171. +}
  24172. +
  24173. +static ssize_t ar71xx_wdt_write(struct file *file, const char *data,
  24174. + size_t len, loff_t *ppos)
  24175. +{
  24176. + if (len) {
  24177. + if (!nowayout) {
  24178. + size_t i;
  24179. +
  24180. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  24181. +
  24182. + for (i = 0; i != len; i++) {
  24183. + char c;
  24184. +
  24185. + if (get_user(c, data + i))
  24186. + return -EFAULT;
  24187. +
  24188. + if (c == 'V')
  24189. + set_bit(WDT_FLAGS_EXPECT_CLOSE,
  24190. + &wdt_flags);
  24191. + }
  24192. + }
  24193. +
  24194. + ar71xx_wdt_keepalive();
  24195. + }
  24196. +
  24197. + return len;
  24198. +}
  24199. +
  24200. +static struct watchdog_info ar71xx_wdt_info = {
  24201. + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
  24202. + WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
  24203. + .firmware_version = 0,
  24204. + .identity = "AR71XX watchdog",
  24205. +};
  24206. +
  24207. +static long ar71xx_wdt_ioctl(struct file *file,
  24208. + unsigned int cmd, unsigned long arg)
  24209. +{
  24210. + int t;
  24211. + int ret;
  24212. +
  24213. + switch (cmd) {
  24214. + case WDIOC_GETSUPPORT:
  24215. + ret = copy_to_user((struct watchdog_info *)arg,
  24216. + &ar71xx_wdt_info,
  24217. + sizeof(ar71xx_wdt_info)) ? -EFAULT : 0;
  24218. + break;
  24219. +
  24220. + case WDIOC_GETSTATUS:
  24221. + ret = put_user(0, (int *)arg) ? -EFAULT : 0;
  24222. + break;
  24223. +
  24224. + case WDIOC_GETBOOTSTATUS:
  24225. + ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0;
  24226. + break;
  24227. +
  24228. + case WDIOC_KEEPALIVE:
  24229. + ar71xx_wdt_keepalive();
  24230. + ret = 0;
  24231. + break;
  24232. +
  24233. + case WDIOC_SETTIMEOUT:
  24234. + ret = get_user(t, (int *)arg) ? -EFAULT : 0;
  24235. + if (ret)
  24236. + break;
  24237. +
  24238. + ret = ar71xx_wdt_set_timeout(t);
  24239. + if (ret)
  24240. + break;
  24241. +
  24242. + /* fallthrough */
  24243. + case WDIOC_GETTIMEOUT:
  24244. + ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0;
  24245. + break;
  24246. +
  24247. + default:
  24248. + ret = -ENOTTY;
  24249. + break;
  24250. + }
  24251. +
  24252. + return ret;
  24253. +}
  24254. +
  24255. +static const struct file_operations ar71xx_wdt_fops = {
  24256. + .owner = THIS_MODULE,
  24257. + .write = ar71xx_wdt_write,
  24258. + .unlocked_ioctl = ar71xx_wdt_ioctl,
  24259. + .open = ar71xx_wdt_open,
  24260. + .release = ar71xx_wdt_release,
  24261. +};
  24262. +
  24263. +static struct miscdevice ar71xx_wdt_miscdev = {
  24264. + .minor = WATCHDOG_MINOR,
  24265. + .name = "watchdog",
  24266. + .fops = &ar71xx_wdt_fops,
  24267. +};
  24268. +
  24269. +static int __devinit ar71xx_wdt_probe(struct platform_device *pdev)
  24270. +{
  24271. + int ret;
  24272. +
  24273. + switch (ar71xx_soc) {
  24274. + case AR71XX_SOC_AR7130:
  24275. + case AR71XX_SOC_AR7141:
  24276. + case AR71XX_SOC_AR7161:
  24277. + case AR71XX_SOC_AR7240:
  24278. + case AR71XX_SOC_AR7241:
  24279. + case AR71XX_SOC_AR7242:
  24280. + case AR71XX_SOC_AR9130:
  24281. + case AR71XX_SOC_AR9132:
  24282. + wdt_clk_freq = ar71xx_ahb_freq;
  24283. + break;
  24284. +
  24285. + case AR71XX_SOC_AR9330:
  24286. + case AR71XX_SOC_AR9331:
  24287. + case AR71XX_SOC_AR9341:
  24288. + case AR71XX_SOC_AR9342:
  24289. + case AR71XX_SOC_AR9344:
  24290. + wdt_clk_freq = ar71xx_ref_freq;
  24291. + break;
  24292. +
  24293. + default:
  24294. + BUG();
  24295. + }
  24296. +
  24297. + max_timeout = (0xfffffffful / wdt_clk_freq);
  24298. + wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
  24299. +
  24300. + if (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET)
  24301. + boot_status = WDIOF_CARDRESET;
  24302. +
  24303. + ret = misc_register(&ar71xx_wdt_miscdev);
  24304. + if (ret)
  24305. + goto err_out;
  24306. +
  24307. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  24308. +
  24309. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n",
  24310. + wdt_timeout, max_timeout);
  24311. +
  24312. + return 0;
  24313. +
  24314. +err_out:
  24315. + return ret;
  24316. +}
  24317. +
  24318. +static int __devexit ar71xx_wdt_remove(struct platform_device *pdev)
  24319. +{
  24320. + misc_deregister(&ar71xx_wdt_miscdev);
  24321. + return 0;
  24322. +}
  24323. +
  24324. +static struct platform_driver ar71xx_wdt_driver = {
  24325. + .probe = ar71xx_wdt_probe,
  24326. + .remove = __devexit_p(ar71xx_wdt_remove),
  24327. + .driver = {
  24328. + .name = DRV_NAME,
  24329. + .owner = THIS_MODULE,
  24330. + },
  24331. +};
  24332. +
  24333. +static int __init ar71xx_wdt_init(void)
  24334. +{
  24335. + return platform_driver_register(&ar71xx_wdt_driver);
  24336. +}
  24337. +module_init(ar71xx_wdt_init);
  24338. +
  24339. +static void __exit ar71xx_wdt_exit(void)
  24340. +{
  24341. + platform_driver_unregister(&ar71xx_wdt_driver);
  24342. +}
  24343. +module_exit(ar71xx_wdt_exit);
  24344. +
  24345. +MODULE_DESCRIPTION(DRV_DESC);
  24346. +MODULE_VERSION(DRV_VERSION);
  24347. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
  24348. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
  24349. +MODULE_LICENSE("GPL v2");
  24350. +MODULE_ALIAS("platform:" DRV_NAME);
  24351. +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  24352. diff -Nur linux-2.6.39.orig/include/linux/ath9k_platform.h linux-2.6.39/include/linux/ath9k_platform.h
  24353. --- linux-2.6.39.orig/include/linux/ath9k_platform.h 2011-05-19 06:06:34.000000000 +0200
  24354. +++ linux-2.6.39/include/linux/ath9k_platform.h 2011-08-24 18:17:24.000000000 +0200
  24355. @@ -23,6 +23,15 @@
  24356. struct ath9k_platform_data {
  24357. u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  24358. + u8 *macaddr;
  24359. +
  24360. + int led_pin;
  24361. + u32 gpio_mask;
  24362. + u32 gpio_val;
  24363. +
  24364. + bool is_clk_25mhz;
  24365. + int (*get_mac_revision)(void);
  24366. + int (*external_reset)(void);
  24367. };
  24368. #endif /* _LINUX_ATH9K_PLATFORM_H */
  24369. diff -Nur linux-2.6.39.orig/include/linux/ip.h linux-2.6.39/include/linux/ip.h
  24370. --- linux-2.6.39.orig/include/linux/ip.h 2011-05-19 06:06:34.000000000 +0200
  24371. +++ linux-2.6.39/include/linux/ip.h 2011-08-24 18:17:24.000000000 +0200
  24372. @@ -102,7 +102,7 @@
  24373. __be32 saddr;
  24374. __be32 daddr;
  24375. /*The options start here. */
  24376. -};
  24377. +} __packed;
  24378. #ifdef __KERNEL__
  24379. #include <linux/skbuff.h>
  24380. diff -Nur linux-2.6.39.orig/include/linux/ipv6.h linux-2.6.39/include/linux/ipv6.h
  24381. --- linux-2.6.39.orig/include/linux/ipv6.h 2011-05-19 06:06:34.000000000 +0200
  24382. +++ linux-2.6.39/include/linux/ipv6.h 2011-08-24 18:17:24.000000000 +0200
  24383. @@ -126,7 +126,7 @@
  24384. struct in6_addr saddr;
  24385. struct in6_addr daddr;
  24386. -};
  24387. +} __packed;
  24388. #ifdef __KERNEL__
  24389. /*
  24390. diff -Nur linux-2.6.39.orig/include/linux/myloader.h linux-2.6.39/include/linux/myloader.h
  24391. --- linux-2.6.39.orig/include/linux/myloader.h 1970-01-01 01:00:00.000000000 +0100
  24392. +++ linux-2.6.39/include/linux/myloader.h 2011-08-24 18:17:24.000000000 +0200
  24393. @@ -0,0 +1,120 @@
  24394. +/*
  24395. + * Compex's MyLoader specific definitions
  24396. + *
  24397. + * Copyright (C) 2006-2008 Gabor Juhos <juhosg@openwrt.org>
  24398. + *
  24399. + * This program is free software; you can redistribute it and/or modify it
  24400. + * under the terms of the GNU General Public License version 2 as published
  24401. + * by the Free Software Foundation.
  24402. + *
  24403. + */
  24404. +
  24405. +#ifndef _MYLOADER_H_
  24406. +#define _MYLOADER_H_
  24407. +
  24408. +/* Myloader specific magic numbers */
  24409. +#define MYLO_MAGIC_SYS_PARAMS 0x20021107
  24410. +#define MYLO_MAGIC_PARTITIONS 0x20021103
  24411. +#define MYLO_MAGIC_BOARD_PARAMS 0x20021103
  24412. +
  24413. +/* Vendor ID's (seems to be same as the PCI vendor ID's) */
  24414. +#define VENID_COMPEX 0x11F6
  24415. +
  24416. +/* Devices based on the ADM5120 */
  24417. +#define DEVID_COMPEX_NP27G 0x0078
  24418. +#define DEVID_COMPEX_NP28G 0x044C
  24419. +#define DEVID_COMPEX_NP28GHS 0x044E
  24420. +#define DEVID_COMPEX_WP54Gv1C 0x0514
  24421. +#define DEVID_COMPEX_WP54G 0x0515
  24422. +#define DEVID_COMPEX_WP54AG 0x0546
  24423. +#define DEVID_COMPEX_WPP54AG 0x0550
  24424. +#define DEVID_COMPEX_WPP54G 0x0555
  24425. +
  24426. +/* Devices based on the Atheros AR2317 */
  24427. +#define DEVID_COMPEX_NP25G 0x05E6
  24428. +#define DEVID_COMPEX_WPE53G 0x05DC
  24429. +
  24430. +/* Devices based on the Atheros AR71xx */
  24431. +#define DEVID_COMPEX_WP543 0x0640
  24432. +
  24433. +/* Devices based on the IXP422 */
  24434. +#define DEVID_COMPEX_WP18 0x047E
  24435. +#define DEVID_COMPEX_NP18A 0x0489
  24436. +
  24437. +/* Other devices */
  24438. +#define DEVID_COMPEX_NP26G8M 0x03E8
  24439. +#define DEVID_COMPEX_NP26G16M 0x03E9
  24440. +
  24441. +struct mylo_partition {
  24442. + uint16_t flags; /* partition flags */
  24443. + uint16_t type; /* type of the partition */
  24444. + uint32_t addr; /* relative address of the partition from the
  24445. + flash start */
  24446. + uint32_t size; /* size of the partition in bytes */
  24447. + uint32_t param; /* if this is the active partition, the
  24448. + MyLoader load code to this address */
  24449. +};
  24450. +
  24451. +#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition,
  24452. + * MyLoader loads firmware from here */
  24453. +#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */
  24454. +#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */
  24455. +#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM
  24456. + * before decompression */
  24457. +#define PARTITION_FLAG_LZMA 0x0100 /* partition data compressed by LZMA */
  24458. +#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */
  24459. +
  24460. +#define PARTITION_TYPE_FREE 0
  24461. +#define PARTITION_TYPE_USED 1
  24462. +
  24463. +#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the
  24464. + partition table */
  24465. +
  24466. +struct mylo_partition_table {
  24467. + uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */
  24468. + uint32_t res0; /* unknown/unused */
  24469. + uint32_t res1; /* unknown/unused */
  24470. + uint32_t res2; /* unknown/unused */
  24471. + struct mylo_partition partitions[MYLO_MAX_PARTITIONS];
  24472. +};
  24473. +
  24474. +struct mylo_partition_header {
  24475. + uint32_t len; /* length of the partition data */
  24476. + uint32_t crc; /* CRC value of the partition data */
  24477. +};
  24478. +
  24479. +struct mylo_system_params {
  24480. + uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */
  24481. + uint32_t res0;
  24482. + uint32_t res1;
  24483. + uint32_t mylo_ver;
  24484. + uint16_t vid; /* Vendor ID */
  24485. + uint16_t did; /* Device ID */
  24486. + uint16_t svid; /* Sub Vendor ID */
  24487. + uint16_t sdid; /* Sub Device ID */
  24488. + uint32_t rev; /* device revision */
  24489. + uint32_t fwhi;
  24490. + uint32_t fwlo;
  24491. + uint32_t tftp_addr;
  24492. + uint32_t prog_start;
  24493. + uint32_t flash_size; /* size of boot FLASH in bytes */
  24494. + uint32_t dram_size; /* size of onboard RAM in bytes */
  24495. +};
  24496. +
  24497. +struct mylo_eth_addr {
  24498. + uint8_t mac[6];
  24499. + uint8_t csum[2];
  24500. +};
  24501. +
  24502. +#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address
  24503. + in the board parameters */
  24504. +
  24505. +struct mylo_board_params {
  24506. + uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */
  24507. + uint32_t res0;
  24508. + uint32_t res1;
  24509. + uint32_t res2;
  24510. + struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT];
  24511. +};
  24512. +
  24513. +#endif /* _MYLOADER_H_*/
  24514. diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux/netdevice.h
  24515. --- linux-2.6.39.orig/include/linux/netdevice.h 2011-05-19 06:06:34.000000000 +0200
  24516. +++ linux-2.6.39/include/linux/netdevice.h 2011-08-24 18:17:24.000000000 +0200
  24517. @@ -1182,6 +1182,7 @@
  24518. void *ax25_ptr; /* AX.25 specific data */
  24519. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  24520. assign before registering */
  24521. + void *phy_ptr; /* PHY device specific data */
  24522. /*
  24523. * Cache lines mostly used on receive path (including eth_type_trans())
  24524. diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/linux/nxp_74hc153.h
  24525. --- linux-2.6.39.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100
  24526. +++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-08-24 18:17:24.000000000 +0200
  24527. @@ -0,0 +1,24 @@
  24528. +/*
  24529. + * NXP 74HC153 - Dual 4-input multiplexer defines
  24530. + *
  24531. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  24532. + *
  24533. + * This program is free software; you can redistribute it and/or modify
  24534. + * it under the terms of the GNU General Public License version 2 as
  24535. + * published by the Free Software Foundation.
  24536. + */
  24537. +
  24538. +#ifndef _NXP_74HC153_H
  24539. +#define _NXP_74HC153_H
  24540. +
  24541. +#define NXP_74HC153_DRIVER_NAME "nxp-74hc153"
  24542. +
  24543. +struct nxp_74hc153_platform_data {
  24544. + unsigned gpio_base;
  24545. + unsigned gpio_pin_s0;
  24546. + unsigned gpio_pin_s1;
  24547. + unsigned gpio_pin_1y;
  24548. + unsigned gpio_pin_2y;
  24549. +};
  24550. +
  24551. +#endif /* _NXP_74HC153_H */
  24552. diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h
  24553. --- linux-2.6.39.orig/include/linux/phy.h 2011-05-19 06:06:34.000000000 +0200
  24554. +++ linux-2.6.39/include/linux/phy.h 2011-08-24 18:17:24.000000000 +0200
  24555. @@ -332,6 +332,20 @@
  24556. void (*adjust_link)(struct net_device *dev);
  24557. void (*adjust_state)(struct net_device *dev);
  24558. +
  24559. + /*
  24560. + * By default these point to the original functions
  24561. + * with the same name. adding them to the phy_device
  24562. + * allows the phy driver to override them for packet
  24563. + * mangling if the ethernet driver supports it
  24564. + * This is required to support some really horrible
  24565. + * switches such as the Marvell 88E6060
  24566. + */
  24567. + int (*netif_receive_skb)(struct sk_buff *skb);
  24568. + int (*netif_rx)(struct sk_buff *skb);
  24569. +
  24570. + /* alignment offset for packets */
  24571. + int pkt_align;
  24572. };
  24573. #define to_phy_device(d) container_of(d, struct phy_device, dev)
  24574. @@ -508,6 +522,7 @@
  24575. void phy_stop_machine(struct phy_device *phydev);
  24576. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  24577. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  24578. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  24579. int phy_mii_ioctl(struct phy_device *phydev,
  24580. struct ifreq *ifr, int cmd);
  24581. int phy_start_interrupts(struct phy_device *phydev);
  24582. diff -Nur linux-2.6.39.orig/include/linux/spi/spi.h linux-2.6.39/include/linux/spi/spi.h
  24583. --- linux-2.6.39.orig/include/linux/spi/spi.h 2011-05-19 06:06:34.000000000 +0200
  24584. +++ linux-2.6.39/include/linux/spi/spi.h 2011-08-24 18:17:24.000000000 +0200
  24585. @@ -441,6 +441,8 @@
  24586. dma_addr_t rx_dma;
  24587. unsigned cs_change:1;
  24588. + unsigned verify:1;
  24589. + unsigned fast_write:1;
  24590. u8 bits_per_word;
  24591. u16 delay_usecs;
  24592. u32 speed_hz;
  24593. @@ -482,6 +484,7 @@
  24594. struct spi_device *spi;
  24595. unsigned is_dma_mapped:1;
  24596. + unsigned fast_read:1;
  24597. /* REVISIT: we might want a flag affecting the behavior of the
  24598. * last transfer ... allowing things like "read 16 bit length L"
  24599. diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/linux/spi/vsc7385.h
  24600. --- linux-2.6.39.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100
  24601. +++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-08-24 18:17:24.000000000 +0200
  24602. @@ -0,0 +1,19 @@
  24603. +/*
  24604. + * Platform data definition for the Vitesse VSC7385 ethernet switch driver
  24605. + *
  24606. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  24607. + *
  24608. + * This program is free software; you can redistribute it and/or modify it
  24609. + * under the terms of the GNU General Public License version 2 as published
  24610. + * by the Free Software Foundation.
  24611. + */
  24612. +
  24613. +struct vsc7385_platform_data {
  24614. + void (*reset)(void);
  24615. + char *ucode_name;
  24616. + struct {
  24617. + u32 tx_ipg:5;
  24618. + u32 bit2:1;
  24619. + u32 clk_sel:3;
  24620. + } mac_cfg;
  24621. +};
  24622. diff -Nur linux-2.6.39.orig/include/linux/switch.h linux-2.6.39/include/linux/switch.h
  24623. --- linux-2.6.39.orig/include/linux/switch.h 1970-01-01 01:00:00.000000000 +0100
  24624. +++ linux-2.6.39/include/linux/switch.h 2011-08-24 18:17:24.000000000 +0200
  24625. @@ -0,0 +1,204 @@
  24626. +/*
  24627. + * switch.h: Switch configuration API
  24628. + *
  24629. + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
  24630. + *
  24631. + * This program is free software; you can redistribute it and/or
  24632. + * modify it under the terms of the GNU General Public License
  24633. + * as published by the Free Software Foundation; either version 2
  24634. + * of the License, or (at your option) any later version.
  24635. + *
  24636. + * This program is distributed in the hope that it will be useful,
  24637. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24638. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24639. + * GNU General Public License for more details.
  24640. + */
  24641. +
  24642. +#ifndef __LINUX_SWITCH_H
  24643. +#define __LINUX_SWITCH_H
  24644. +
  24645. +#include <linux/types.h>
  24646. +#include <linux/netdevice.h>
  24647. +#include <linux/netlink.h>
  24648. +#include <linux/genetlink.h>
  24649. +#ifndef __KERNEL__
  24650. +#include <netlink/netlink.h>
  24651. +#include <netlink/genl/genl.h>
  24652. +#include <netlink/genl/ctrl.h>
  24653. +#else
  24654. +#include <net/genetlink.h>
  24655. +#endif
  24656. +
  24657. +/* main attributes */
  24658. +enum {
  24659. + SWITCH_ATTR_UNSPEC,
  24660. + /* global */
  24661. + SWITCH_ATTR_TYPE,
  24662. + /* device */
  24663. + SWITCH_ATTR_ID,
  24664. + SWITCH_ATTR_DEV_NAME,
  24665. + SWITCH_ATTR_ALIAS,
  24666. + SWITCH_ATTR_NAME,
  24667. + SWITCH_ATTR_VLANS,
  24668. + SWITCH_ATTR_PORTS,
  24669. + SWITCH_ATTR_CPU_PORT,
  24670. + /* attributes */
  24671. + SWITCH_ATTR_OP_ID,
  24672. + SWITCH_ATTR_OP_TYPE,
  24673. + SWITCH_ATTR_OP_NAME,
  24674. + SWITCH_ATTR_OP_PORT,
  24675. + SWITCH_ATTR_OP_VLAN,
  24676. + SWITCH_ATTR_OP_VALUE_INT,
  24677. + SWITCH_ATTR_OP_VALUE_STR,
  24678. + SWITCH_ATTR_OP_VALUE_PORTS,
  24679. + SWITCH_ATTR_OP_DESCRIPTION,
  24680. + /* port lists */
  24681. + SWITCH_ATTR_PORT,
  24682. + SWITCH_ATTR_MAX
  24683. +};
  24684. +
  24685. +/* commands */
  24686. +enum {
  24687. + SWITCH_CMD_UNSPEC,
  24688. + SWITCH_CMD_GET_SWITCH,
  24689. + SWITCH_CMD_NEW_ATTR,
  24690. + SWITCH_CMD_LIST_GLOBAL,
  24691. + SWITCH_CMD_GET_GLOBAL,
  24692. + SWITCH_CMD_SET_GLOBAL,
  24693. + SWITCH_CMD_LIST_PORT,
  24694. + SWITCH_CMD_GET_PORT,
  24695. + SWITCH_CMD_SET_PORT,
  24696. + SWITCH_CMD_LIST_VLAN,
  24697. + SWITCH_CMD_GET_VLAN,
  24698. + SWITCH_CMD_SET_VLAN
  24699. +};
  24700. +
  24701. +/* data types */
  24702. +enum switch_val_type {
  24703. + SWITCH_TYPE_UNSPEC,
  24704. + SWITCH_TYPE_INT,
  24705. + SWITCH_TYPE_STRING,
  24706. + SWITCH_TYPE_PORTS,
  24707. + SWITCH_TYPE_NOVAL,
  24708. +};
  24709. +
  24710. +/* port nested attributes */
  24711. +enum {
  24712. + SWITCH_PORT_UNSPEC,
  24713. + SWITCH_PORT_ID,
  24714. + SWITCH_PORT_FLAG_TAGGED,
  24715. + SWITCH_PORT_ATTR_MAX
  24716. +};
  24717. +
  24718. +#define SWITCH_ATTR_DEFAULTS_OFFSET 0x1000
  24719. +
  24720. +#ifdef __KERNEL__
  24721. +
  24722. +struct switch_dev;
  24723. +struct switch_op;
  24724. +struct switch_val;
  24725. +struct switch_attr;
  24726. +struct switch_attrlist;
  24727. +
  24728. +int register_switch(struct switch_dev *dev, struct net_device *netdev);
  24729. +void unregister_switch(struct switch_dev *dev);
  24730. +
  24731. +/**
  24732. + * struct switch_attrlist - attribute list
  24733. + *
  24734. + * @n_attr: number of attributes
  24735. + * @attr: pointer to the attributes array
  24736. + */
  24737. +struct switch_attrlist {
  24738. + int n_attr;
  24739. + const struct switch_attr *attr;
  24740. +};
  24741. +
  24742. +/**
  24743. + * struct switch_dev_ops - switch driver operations
  24744. + *
  24745. + * @attr_global: global switch attribute list
  24746. + * @attr_port: port attribute list
  24747. + * @attr_vlan: vlan attribute list
  24748. + *
  24749. + * Callbacks:
  24750. + *
  24751. + * @get_vlan_ports: read the port list of a VLAN
  24752. + * @set_vlan_ports: set the port list of a VLAN
  24753. + *
  24754. + * @get_port_pvid: get the primary VLAN ID of a port
  24755. + * @set_port_pvid: set the primary VLAN ID of a port
  24756. + *
  24757. + * @apply_config: apply all changed settings to the switch
  24758. + * @reset_switch: resetting the switch
  24759. + */
  24760. +struct switch_dev_ops {
  24761. + struct switch_attrlist attr_global, attr_port, attr_vlan;
  24762. +
  24763. + int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
  24764. + int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
  24765. +
  24766. + int (*get_port_pvid)(struct switch_dev *dev, int port, int *val);
  24767. + int (*set_port_pvid)(struct switch_dev *dev, int port, int val);
  24768. +
  24769. + int (*apply_config)(struct switch_dev *dev);
  24770. + int (*reset_switch)(struct switch_dev *dev);
  24771. +};
  24772. +
  24773. +struct switch_dev {
  24774. + const struct switch_dev_ops *ops;
  24775. + /* will be automatically filled */
  24776. + char devname[IFNAMSIZ];
  24777. +
  24778. + const char *name;
  24779. + /* NB: either alias or netdev must be set */
  24780. + const char *alias;
  24781. + struct net_device *netdev;
  24782. +
  24783. + int ports;
  24784. + int vlans;
  24785. + int cpu_port;
  24786. +
  24787. + /* the following fields are internal for swconfig */
  24788. + int id;
  24789. + struct list_head dev_list;
  24790. + unsigned long def_global, def_port, def_vlan;
  24791. +
  24792. + spinlock_t lock;
  24793. + struct switch_port *portbuf;
  24794. +};
  24795. +
  24796. +struct switch_port {
  24797. + u32 id;
  24798. + u32 flags;
  24799. +};
  24800. +
  24801. +struct switch_val {
  24802. + const struct switch_attr *attr;
  24803. + int port_vlan;
  24804. + int len;
  24805. + union {
  24806. + const char *s;
  24807. + u32 i;
  24808. + struct switch_port *ports;
  24809. + } value;
  24810. +};
  24811. +
  24812. +struct switch_attr {
  24813. + int disabled;
  24814. + int type;
  24815. + const char *name;
  24816. + const char *description;
  24817. +
  24818. + int (*set)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val);
  24819. + int (*get)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val);
  24820. +
  24821. + /* for driver internal use */
  24822. + int id;
  24823. + int ofs;
  24824. + int max;
  24825. +};
  24826. +
  24827. +#endif
  24828. +
  24829. +#endif
  24830. diff -Nur linux-2.6.39.orig/include/linux/tcp.h linux-2.6.39/include/linux/tcp.h
  24831. --- linux-2.6.39.orig/include/linux/tcp.h 2011-05-19 06:06:34.000000000 +0200
  24832. +++ linux-2.6.39/include/linux/tcp.h 2011-08-24 18:17:24.000000000 +0200
  24833. @@ -54,7 +54,7 @@
  24834. __be16 window;
  24835. __sum16 check;
  24836. __be16 urg_ptr;
  24837. -};
  24838. +} __packed;
  24839. /*
  24840. * The union cast uses a gcc extension to avoid aliasing problems
  24841. diff -Nur linux-2.6.39.orig/include/linux/udp.h linux-2.6.39/include/linux/udp.h
  24842. --- linux-2.6.39.orig/include/linux/udp.h 2011-05-19 06:06:34.000000000 +0200
  24843. +++ linux-2.6.39/include/linux/udp.h 2011-08-24 18:17:24.000000000 +0200
  24844. @@ -24,7 +24,7 @@
  24845. __be16 dest;
  24846. __be16 len;
  24847. __sum16 check;
  24848. -};
  24849. +} __packed;
  24850. /* UDP socket options */
  24851. #define UDP_CORK 1 /* Never send partially complete segments */
  24852. diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c
  24853. --- linux-2.6.39.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100
  24854. +++ linux-2.6.39/net/dsa/mv88e6063.c 2011-08-24 18:17:24.000000000 +0200
  24855. @@ -0,0 +1,294 @@
  24856. +/*
  24857. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips
  24858. + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  24859. + *
  24860. + * This driver was base on: net/dsa/mv88e6060.c
  24861. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips
  24862. + * Copyright (c) 2008-2009 Marvell Semiconductor
  24863. + *
  24864. + * This program is free software; you can redistribute it and/or modify
  24865. + * it under the terms of the GNU General Public License as published by
  24866. + * the Free Software Foundation; either version 2 of the License, or
  24867. + * (at your option) any later version.
  24868. + */
  24869. +
  24870. +#include <linux/list.h>
  24871. +#include <linux/netdevice.h>
  24872. +#include <linux/phy.h>
  24873. +#include "dsa_priv.h"
  24874. +
  24875. +#define REG_BASE 0x10
  24876. +#define REG_PHY(p) (REG_BASE + (p))
  24877. +#define REG_PORT(p) (REG_BASE + 8 + (p))
  24878. +#define REG_GLOBAL (REG_BASE + 0x0f)
  24879. +#define NUM_PORTS 7
  24880. +
  24881. +static int reg_read(struct dsa_switch *ds, int addr, int reg)
  24882. +{
  24883. + return mdiobus_read(ds->master_mii_bus, addr, reg);
  24884. +}
  24885. +
  24886. +#define REG_READ(addr, reg) \
  24887. + ({ \
  24888. + int __ret; \
  24889. + \
  24890. + __ret = reg_read(ds, addr, reg); \
  24891. + if (__ret < 0) \
  24892. + return __ret; \
  24893. + __ret; \
  24894. + })
  24895. +
  24896. +
  24897. +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
  24898. +{
  24899. + return mdiobus_write(ds->master_mii_bus, addr, reg, val);
  24900. +}
  24901. +
  24902. +#define REG_WRITE(addr, reg, val) \
  24903. + ({ \
  24904. + int __ret; \
  24905. + \
  24906. + __ret = reg_write(ds, addr, reg, val); \
  24907. + if (__ret < 0) \
  24908. + return __ret; \
  24909. + })
  24910. +
  24911. +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr)
  24912. +{
  24913. + int ret;
  24914. +
  24915. + ret = mdiobus_read(bus, REG_PORT(0), 0x03);
  24916. + if (ret >= 0) {
  24917. + ret &= 0xfff0;
  24918. + if (ret == 0x1530)
  24919. + return "Marvell 88E6063";
  24920. + }
  24921. +
  24922. + return NULL;
  24923. +}
  24924. +
  24925. +static int mv88e6063_switch_reset(struct dsa_switch *ds)
  24926. +{
  24927. + int i;
  24928. + int ret;
  24929. +
  24930. + /*
  24931. + * Set all ports to the disabled state.
  24932. + */
  24933. + for (i = 0; i < NUM_PORTS; i++) {
  24934. + ret = REG_READ(REG_PORT(i), 0x04);
  24935. + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
  24936. + }
  24937. +
  24938. + /*
  24939. + * Wait for transmit queues to drain.
  24940. + */
  24941. + msleep(2);
  24942. +
  24943. + /*
  24944. + * Reset the switch.
  24945. + */
  24946. + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130);
  24947. +
  24948. + /*
  24949. + * Wait up to one second for reset to complete.
  24950. + */
  24951. + for (i = 0; i < 1000; i++) {
  24952. + ret = REG_READ(REG_GLOBAL, 0x00);
  24953. + if ((ret & 0x8000) == 0x0000)
  24954. + break;
  24955. +
  24956. + msleep(1);
  24957. + }
  24958. + if (i == 1000)
  24959. + return -ETIMEDOUT;
  24960. +
  24961. + return 0;
  24962. +}
  24963. +
  24964. +static int mv88e6063_setup_global(struct dsa_switch *ds)
  24965. +{
  24966. + /*
  24967. + * Disable discarding of frames with excessive collisions,
  24968. + * set the maximum frame size to 1536 bytes, and mask all
  24969. + * interrupt sources.
  24970. + */
  24971. + REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
  24972. +
  24973. + /*
  24974. + * Enable automatic address learning, set the address
  24975. + * database size to 1024 entries, and set the default aging
  24976. + * time to 5 minutes.
  24977. + */
  24978. + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
  24979. +
  24980. + return 0;
  24981. +}
  24982. +
  24983. +static int mv88e6063_setup_port(struct dsa_switch *ds, int p)
  24984. +{
  24985. + int addr = REG_PORT(p);
  24986. +
  24987. + /*
  24988. + * Do not force flow control, disable Ingress and Egress
  24989. + * Header tagging, disable VLAN tunneling, and set the port
  24990. + * state to Forwarding. Additionally, if this is the CPU
  24991. + * port, enable Ingress and Egress Trailer tagging mode.
  24992. + */
  24993. + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003);
  24994. +
  24995. + /*
  24996. + * Port based VLAN map: give each port its own address
  24997. + * database, allow the CPU port to talk to each of the 'real'
  24998. + * ports, and allow each of the 'real' ports to only talk to
  24999. + * the CPU port.
  25000. + */
  25001. + REG_WRITE(addr, 0x06,
  25002. + ((p & 0xf) << 12) |
  25003. + (dsa_is_cpu_port(ds, p) ?
  25004. + ds->phys_port_mask :
  25005. + (1 << ds->dst->cpu_port)));
  25006. +
  25007. + /*
  25008. + * Port Association Vector: when learning source addresses
  25009. + * of packets, add the address to the address database using
  25010. + * a port bitmap that has only the bit for this port set and
  25011. + * the other bits clear.
  25012. + */
  25013. + REG_WRITE(addr, 0x0b, 1 << p);
  25014. +
  25015. + return 0;
  25016. +}
  25017. +
  25018. +static int mv88e6063_setup(struct dsa_switch *ds)
  25019. +{
  25020. + int i;
  25021. + int ret;
  25022. +
  25023. + ret = mv88e6063_switch_reset(ds);
  25024. + if (ret < 0)
  25025. + return ret;
  25026. +
  25027. + /* @@@ initialise atu */
  25028. +
  25029. + ret = mv88e6063_setup_global(ds);
  25030. + if (ret < 0)
  25031. + return ret;
  25032. +
  25033. + for (i = 0; i < NUM_PORTS; i++) {
  25034. + ret = mv88e6063_setup_port(ds, i);
  25035. + if (ret < 0)
  25036. + return ret;
  25037. + }
  25038. +
  25039. + return 0;
  25040. +}
  25041. +
  25042. +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr)
  25043. +{
  25044. + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
  25045. + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
  25046. + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
  25047. +
  25048. + return 0;
  25049. +}
  25050. +
  25051. +static int mv88e6063_port_to_phy_addr(int port)
  25052. +{
  25053. + if (port >= 0 && port <= NUM_PORTS)
  25054. + return REG_PHY(port);
  25055. + return -1;
  25056. +}
  25057. +
  25058. +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum)
  25059. +{
  25060. + int addr;
  25061. +
  25062. + addr = mv88e6063_port_to_phy_addr(port);
  25063. + if (addr == -1)
  25064. + return 0xffff;
  25065. +
  25066. + return reg_read(ds, addr, regnum);
  25067. +}
  25068. +
  25069. +static int
  25070. +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
  25071. +{
  25072. + int addr;
  25073. +
  25074. + addr = mv88e6063_port_to_phy_addr(port);
  25075. + if (addr == -1)
  25076. + return 0xffff;
  25077. +
  25078. + return reg_write(ds, addr, regnum, val);
  25079. +}
  25080. +
  25081. +static void mv88e6063_poll_link(struct dsa_switch *ds)
  25082. +{
  25083. + int i;
  25084. +
  25085. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  25086. + struct net_device *dev;
  25087. + int uninitialized_var(port_status);
  25088. + int link;
  25089. + int speed;
  25090. + int duplex;
  25091. + int fc;
  25092. +
  25093. + dev = ds->ports[i];
  25094. + if (dev == NULL)
  25095. + continue;
  25096. +
  25097. + link = 0;
  25098. + if (dev->flags & IFF_UP) {
  25099. + port_status = reg_read(ds, REG_PORT(i), 0x00);
  25100. + if (port_status < 0)
  25101. + continue;
  25102. +
  25103. + link = !!(port_status & 0x1000);
  25104. + }
  25105. +
  25106. + if (!link) {
  25107. + if (netif_carrier_ok(dev)) {
  25108. + printk(KERN_INFO "%s: link down\n", dev->name);
  25109. + netif_carrier_off(dev);
  25110. + }
  25111. + continue;
  25112. + }
  25113. +
  25114. + speed = (port_status & 0x0100) ? 100 : 10;
  25115. + duplex = (port_status & 0x0200) ? 1 : 0;
  25116. + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
  25117. +
  25118. + if (!netif_carrier_ok(dev)) {
  25119. + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
  25120. + "flow control %sabled\n", dev->name,
  25121. + speed, duplex ? "full" : "half",
  25122. + fc ? "en" : "dis");
  25123. + netif_carrier_on(dev);
  25124. + }
  25125. + }
  25126. +}
  25127. +
  25128. +static struct dsa_switch_driver mv88e6063_switch_driver = {
  25129. + .tag_protocol = htons(ETH_P_TRAILER),
  25130. + .probe = mv88e6063_probe,
  25131. + .setup = mv88e6063_setup,
  25132. + .set_addr = mv88e6063_set_addr,
  25133. + .phy_read = mv88e6063_phy_read,
  25134. + .phy_write = mv88e6063_phy_write,
  25135. + .poll_link = mv88e6063_poll_link,
  25136. +};
  25137. +
  25138. +static int __init mv88e6063_init(void)
  25139. +{
  25140. + register_switch_driver(&mv88e6063_switch_driver);
  25141. + return 0;
  25142. +}
  25143. +module_init(mv88e6063_init);
  25144. +
  25145. +static void __exit mv88e6063_cleanup(void)
  25146. +{
  25147. + unregister_switch_driver(&mv88e6063_switch_driver);
  25148. +}
  25149. +module_exit(mv88e6063_cleanup);
  25150. diff -Nur linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
  25151. --- linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-05-19 06:06:34.000000000 +0200
  25152. +++ linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-08-24 18:17:24.000000000 +0200
  25153. @@ -14,6 +14,7 @@
  25154. #include <linux/skbuff.h>
  25155. #include <linux/icmp.h>
  25156. #include <linux/sysctl.h>
  25157. +#include <linux/unaligned/packed_struct.h>
  25158. #include <net/route.h>
  25159. #include <net/ip.h>
  25160. @@ -44,8 +45,8 @@
  25161. if (ap == NULL)
  25162. return false;
  25163. - tuple->src.u3.ip = ap[0];
  25164. - tuple->dst.u3.ip = ap[1];
  25165. + tuple->src.u3.ip = __get_unaligned_cpu32(ap++);
  25166. + tuple->dst.u3.ip = __get_unaligned_cpu32(ap);
  25167. return true;
  25168. }