1
0

ar71xx.patch 489 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666
  1. diff -Nur linux-2.6.36.orig/arch/mips/Kconfig linux-2.6.36/arch/mips/Kconfig
  2. --- linux-2.6.36.orig/arch/mips/Kconfig 2010-10-20 22:30:22.000000000 +0200
  3. +++ linux-2.6.36/arch/mips/Kconfig 2010-12-17 18:34:51.000000000 +0100
  4. @@ -60,6 +60,23 @@
  5. Support for the Texas Instruments AR7 System-on-a-Chip
  6. family: TNETD7100, 7200 and 7300.
  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. @@ -709,6 +726,7 @@
  28. endchoice
  29. source "arch/mips/alchemy/Kconfig"
  30. +source "arch/mips/ar71xx/Kconfig"
  31. source "arch/mips/bcm63xx/Kconfig"
  32. source "arch/mips/jazz/Kconfig"
  33. source "arch/mips/jz4740/Kconfig"
  34. @@ -872,9 +890,15 @@
  35. config MIPS_DISABLE_OBSOLETE_IDE
  36. bool
  37. +config MYLOADER
  38. + bool
  39. +
  40. config SYNC_R4K
  41. bool
  42. +config MIPS_MACHINE
  43. + def_bool n
  44. +
  45. config NO_IOPORT
  46. def_bool n
  47. diff -Nur linux-2.6.36.orig/arch/mips/Makefile linux-2.6.36/arch/mips/Makefile
  48. --- linux-2.6.36.orig/arch/mips/Makefile 2010-10-20 22:30:22.000000000 +0200
  49. +++ linux-2.6.36/arch/mips/Makefile 2010-12-17 18:34:51.000000000 +0100
  50. @@ -160,6 +160,13 @@
  51. cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
  52. endif
  53. +#
  54. +# Atheros AR71xx
  55. +#
  56. +core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
  57. +cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
  58. +load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
  59. +
  60. cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
  61. cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
  62. cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
  63. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/Kconfig linux-2.6.36/arch/mips/ar71xx/Kconfig
  64. --- linux-2.6.36.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  65. +++ linux-2.6.36/arch/mips/ar71xx/Kconfig 2010-12-17 18:34:51.000000000 +0100
  66. @@ -0,0 +1,264 @@
  67. +if ATHEROS_AR71XX
  68. +
  69. +menu "Atheros AR71xx machine selection"
  70. +
  71. +config AR71XX_MACH_AP81
  72. + bool "Atheros AP81 board support"
  73. + select AR71XX_DEV_M25P80
  74. + select AR71XX_DEV_AR913X_WMAC
  75. + select AR71XX_DEV_GPIO_BUTTONS
  76. + select AR71XX_DEV_LEDS_GPIO
  77. + select AR71XX_DEV_USB
  78. + default n
  79. +
  80. +config AR71XX_MACH_AP83
  81. + bool "Atheros AP83 board support"
  82. + select AR71XX_DEV_AR913X_WMAC
  83. + select AR71XX_DEV_GPIO_BUTTONS
  84. + select AR71XX_DEV_LEDS_GPIO
  85. + select AR71XX_DEV_USB
  86. + default n
  87. +
  88. +config AR71XX_MACH_DIR_600_A1
  89. + bool "D-Link DIR-600 rev. A1 support"
  90. + select AR71XX_DEV_AP91_ETH
  91. + select AR71XX_DEV_AP91_PCI if PCI
  92. + select AR71XX_DEV_M25P80
  93. + select AR71XX_DEV_GPIO_BUTTONS
  94. + select AR71XX_DEV_LEDS_GPIO
  95. + select AR71XX_NVRAM
  96. + default n
  97. +
  98. +config AR71XX_MACH_DIR_615_C1
  99. + bool "D-Link DIR-615 rev. C1 support"
  100. + select AR71XX_DEV_M25P80
  101. + select AR71XX_DEV_AR913X_WMAC
  102. + select AR71XX_DEV_GPIO_BUTTONS
  103. + select AR71XX_DEV_LEDS_GPIO
  104. + select AR71XX_NVRAM
  105. + default n
  106. +
  107. +config AR71XX_MACH_DIR_825_B1
  108. + bool "D-Link DIR-825 rev. B1 board support"
  109. + select AR71XX_DEV_M25P80
  110. + select AR71XX_DEV_AP94_PCI if PCI
  111. + select AR71XX_DEV_GPIO_BUTTONS
  112. + select AR71XX_DEV_LEDS_GPIO
  113. + select AR71XX_DEV_USB
  114. + default n
  115. +
  116. +config AR71XX_MACH_PB42
  117. + bool "Atheros PB42 board support"
  118. + select AR71XX_DEV_M25P80
  119. + select AR71XX_DEV_GPIO_BUTTONS
  120. + select AR71XX_DEV_PB42_PCI if PCI
  121. + default n
  122. +
  123. +config AR71XX_MACH_PB44
  124. + bool "Atheros PB44 board support"
  125. + select AR71XX_DEV_GPIO_BUTTONS
  126. + select AR71XX_DEV_PB42_PCI if PCI
  127. + select AR71XX_DEV_LEDS_GPIO
  128. + select AR71XX_DEV_USB
  129. + default n
  130. +
  131. +config AR71XX_MACH_PB92
  132. + bool "Atheros PB92 board support"
  133. + select AR71XX_DEV_GPIO_BUTTONS
  134. + select AR71XX_DEV_PB9X_PCI if PCI
  135. + select AR71XX_DEV_LEDS_GPIO
  136. + select AR71XX_DEV_USB
  137. + default n
  138. +
  139. +config AR71XX_MACH_AW_NR580
  140. + bool "AzureWave AW-NR580 board support"
  141. + select AR71XX_DEV_M25P80
  142. + select AR71XX_DEV_GPIO_BUTTONS
  143. + select AR71XX_DEV_PB42_PCI if PCI
  144. + select AR71XX_DEV_LEDS_GPIO
  145. + default n
  146. +
  147. +config AR71XX_MACH_WZR_HP_G300NH
  148. + bool "Buffalo WZR-HP-G300NH board support"
  149. + select AR71XX_DEV_AR913X_WMAC
  150. + select AR71XX_DEV_GPIO_BUTTONS
  151. + select AR71XX_DEV_LEDS_GPIO
  152. + select AR71XX_DEV_USB
  153. + default y
  154. +
  155. +config AR71XX_MACH_WP543
  156. + bool "Compex WP543/WPJ543 board support"
  157. + select MYLOADER
  158. + select AR71XX_DEV_M25P80
  159. + select AR71XX_DEV_GPIO_BUTTONS
  160. + select AR71XX_DEV_PB42_PCI if PCI
  161. + select AR71XX_DEV_LEDS_GPIO
  162. + select AR71XX_DEV_USB
  163. + default n
  164. +
  165. +config AR71XX_MACH_WRT160NL
  166. + bool "Linksys WRT160NL board support"
  167. + select AR71XX_DEV_M25P80
  168. + select AR71XX_DEV_AR913X_WMAC
  169. + select AR71XX_DEV_GPIO_BUTTONS
  170. + select AR71XX_DEV_LEDS_GPIO
  171. + select AR71XX_DEV_USB
  172. + select AR71XX_NVRAM
  173. + default n
  174. +
  175. +config AR71XX_MACH_WRT400N
  176. + bool "Linksys WRT400N board support"
  177. + select AR71XX_DEV_AP94_PCI if PCI
  178. + select AR71XX_DEV_M25P80
  179. + select AR71XX_DEV_GPIO_BUTTONS
  180. + select AR71XX_DEV_LEDS_GPIO
  181. + default n
  182. +
  183. +config AR71XX_MACH_RB4XX
  184. + bool "MikroTik RouterBOARD 4xx series support"
  185. + select AR71XX_DEV_GPIO_BUTTONS
  186. + select AR71XX_DEV_LEDS_GPIO
  187. + select AR71XX_DEV_USB
  188. + default n
  189. +
  190. +config AR71XX_MACH_RB750
  191. + bool "MikroTik RouterBOARD 750 support"
  192. + select AR71XX_DEV_AP91_ETH
  193. + default n
  194. +
  195. +config AR71XX_MACH_WNDR3700
  196. + bool "NETGEAR WNDR3700 board support"
  197. + select AR71XX_DEV_M25P80
  198. + select AR71XX_DEV_AP94_PCI if PCI
  199. + select AR71XX_DEV_GPIO_BUTTONS
  200. + select AR71XX_DEV_LEDS_GPIO
  201. + select AR71XX_DEV_USB
  202. + default n
  203. +
  204. +config AR71XX_MACH_WNR2000
  205. + bool "NETGEAR WNR2000 board support"
  206. + select AR71XX_DEV_M25P80
  207. + select AR71XX_DEV_AR913X_WMAC
  208. + select AR71XX_DEV_GPIO_BUTTONS
  209. + select AR71XX_DEV_LEDS_GPIO
  210. + default n
  211. +
  212. +config AR71XX_MACH_MZK_W04NU
  213. + bool "Planex MZK-W04NU board support"
  214. + select AR71XX_DEV_M25P80
  215. + select AR71XX_DEV_AR913X_WMAC
  216. + select AR71XX_DEV_GPIO_BUTTONS
  217. + select AR71XX_DEV_LEDS_GPIO
  218. + select AR71XX_DEV_USB
  219. + default n
  220. +
  221. +config AR71XX_MACH_MZK_W300NH
  222. + bool "Planex MZK-W300NH board support"
  223. + select AR71XX_DEV_M25P80
  224. + select AR71XX_DEV_AR913X_WMAC
  225. + select AR71XX_DEV_GPIO_BUTTONS
  226. + select AR71XX_DEV_LEDS_GPIO
  227. + default n
  228. +
  229. +config AR71XX_MACH_NBG460N
  230. + bool "Zyxel NBG460N/550N/550NH board support"
  231. + select AR71XX_DEV_M25P80
  232. + select AR71XX_DEV_AR913X_WMAC
  233. + select AR71XX_DEV_GPIO_BUTTONS
  234. + select AR71XX_DEV_LEDS_GPIO
  235. + default n
  236. +
  237. +config AR71XX_MACH_TL_WR741ND
  238. + bool "TP-LINK TL-WR741ND support"
  239. + select AR71XX_DEV_M25P80
  240. + select AR71XX_DEV_AP91_ETH
  241. + select AR71XX_DEV_AP91_PCI if PCI
  242. + select AR71XX_DEV_GPIO_BUTTONS
  243. + select AR71XX_DEV_LEDS_GPIO
  244. + default n
  245. +
  246. +config AR71XX_MACH_TL_WR841N_V1
  247. + bool "TP-LINK TL-WR841N v1 support"
  248. + select AR71XX_DEV_M25P80
  249. + select AR71XX_DEV_PB42_PCI if PCI
  250. + select AR71XX_DEV_DSA
  251. + select AR71XX_DEV_GPIO_BUTTONS
  252. + select AR71XX_DEV_LEDS_GPIO
  253. + default n
  254. +
  255. +config AR71XX_MACH_TL_WR941ND
  256. + bool "TP-LINK TL-WR941ND support"
  257. + select AR71XX_DEV_M25P80
  258. + select AR71XX_DEV_AR913X_WMAC
  259. + select AR71XX_DEV_DSA
  260. + select AR71XX_DEV_GPIO_BUTTONS
  261. + select AR71XX_DEV_LEDS_GPIO
  262. + default n
  263. +
  264. +config AR71XX_MACH_TL_WR1043ND
  265. + bool "TP-LINK TL-WR1043ND support"
  266. + select AR71XX_DEV_M25P80
  267. + select AR71XX_DEV_AR913X_WMAC
  268. + select AR71XX_DEV_GPIO_BUTTONS
  269. + select AR71XX_DEV_LEDS_GPIO
  270. + select AR71XX_DEV_USB
  271. + default n
  272. +
  273. +config AR71XX_MACH_TEW_632BRP
  274. + bool "TRENDnet TEW-632BRP support"
  275. + select AR71XX_DEV_M25P80
  276. + select AR71XX_DEV_AR913X_WMAC
  277. + select AR71XX_DEV_GPIO_BUTTONS
  278. + select AR71XX_DEV_LEDS_GPIO
  279. + select AR71XX_NVRAM
  280. + default n
  281. +
  282. +config AR71XX_MACH_UBNT
  283. + bool "Ubiquiti AR71xx based boards support"
  284. + select AR71XX_DEV_M25P80
  285. + select AR71XX_DEV_AP91_PCI if PCI
  286. + select AR71XX_DEV_GPIO_BUTTONS
  287. + select AR71XX_DEV_LEDS_GPIO
  288. + select AR71XX_DEV_PB42_PCI if PCI
  289. + select AR71XX_DEV_USB
  290. + default n
  291. +
  292. +endmenu
  293. +
  294. +config AR71XX_DEV_M25P80
  295. + def_bool n
  296. +
  297. +config AR71XX_DEV_AP91_PCI
  298. + def_bool n
  299. +
  300. +config AR71XX_DEV_AP91_ETH
  301. + def_bool n
  302. +
  303. +config AR71XX_DEV_AP94_PCI
  304. + def_bool n
  305. +
  306. +config AR71XX_DEV_AR913X_WMAC
  307. + def_bool n
  308. +
  309. +config AR71XX_DEV_DSA
  310. + def_bool n
  311. +
  312. +config AR71XX_DEV_GPIO_BUTTONS
  313. + def_bool n
  314. +
  315. +config AR71XX_DEV_LEDS_GPIO
  316. + def_bool n
  317. +
  318. +config AR71XX_DEV_PB42_PCI
  319. + def_bool n
  320. +
  321. +config AR71XX_DEV_PB9X_PCI
  322. + def_bool n
  323. +
  324. +config AR71XX_DEV_USB
  325. + def_bool n
  326. +
  327. +config AR71XX_NVRAM
  328. + def_bool n
  329. +
  330. +endif
  331. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/Makefile linux-2.6.36/arch/mips/ar71xx/Makefile
  332. --- linux-2.6.36.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  333. +++ linux-2.6.36/arch/mips/ar71xx/Makefile 2010-12-17 18:34:51.000000000 +0100
  334. @@ -0,0 +1,54 @@
  335. +#
  336. +# Makefile for the Atheros AR71xx SoC specific parts of the kernel
  337. +#
  338. +# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  339. +# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  340. +#
  341. +# This program is free software; you can redistribute it and/or modify it
  342. +# under the terms of the GNU General Public License version 2 as published
  343. +# by the Free Software Foundation.
  344. +
  345. +obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o
  346. +
  347. +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  348. +obj-$(CONFIG_PCI) += pci.o
  349. +
  350. +obj-$(CONFIG_AR71XX_DEV_AP91_ETH) += dev-ap91-eth.o
  351. +obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o
  352. +obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o
  353. +obj-$(CONFIG_AR71XX_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
  354. +obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o
  355. +obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
  356. +obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o
  357. +obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o
  358. +obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o
  359. +obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o
  360. +obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o
  361. +
  362. +obj-$(CONFIG_AR71XX_NVRAM) += nvram.o
  363. +
  364. +obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o
  365. +obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o
  366. +obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o
  367. +obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o
  368. +obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o
  369. +obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o
  370. +obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o
  371. +obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o
  372. +obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o
  373. +obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o
  374. +obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o
  375. +obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o
  376. +obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o
  377. +obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o
  378. +obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o
  379. +obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o
  380. +obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o
  381. +obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o
  382. +obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o
  383. +obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o
  384. +obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o
  385. +obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o
  386. +obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o
  387. +obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o
  388. +obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o
  389. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.36/arch/mips/ar71xx/ar71xx.c
  390. --- linux-2.6.36.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  391. +++ linux-2.6.36/arch/mips/ar71xx/ar71xx.c 2010-12-17 18:34:51.000000000 +0100
  392. @@ -0,0 +1,177 @@
  393. +/*
  394. + * AR71xx SoC routines
  395. + *
  396. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  397. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  398. + *
  399. + * This program is free software; you can redistribute it and/or modify it
  400. + * under the terms of the GNU General Public License version 2 as published
  401. + * by the Free Software Foundation.
  402. + */
  403. +
  404. +#include <linux/kernel.h>
  405. +#include <linux/module.h>
  406. +#include <linux/types.h>
  407. +#include <linux/mutex.h>
  408. +
  409. +#include <asm/mach-ar71xx/ar71xx.h>
  410. +
  411. +static DEFINE_MUTEX(ar71xx_flash_mutex);
  412. +
  413. +void __iomem *ar71xx_ddr_base;
  414. +EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
  415. +
  416. +void __iomem *ar71xx_pll_base;
  417. +EXPORT_SYMBOL_GPL(ar71xx_pll_base);
  418. +
  419. +void __iomem *ar71xx_reset_base;
  420. +EXPORT_SYMBOL_GPL(ar71xx_reset_base);
  421. +
  422. +void __iomem *ar71xx_gpio_base;
  423. +EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
  424. +
  425. +void __iomem *ar71xx_usb_ctrl_base;
  426. +EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
  427. +
  428. +void ar71xx_device_stop(u32 mask)
  429. +{
  430. + unsigned long flags;
  431. + u32 mask_inv;
  432. + u32 t;
  433. +
  434. + switch (ar71xx_soc) {
  435. + case AR71XX_SOC_AR7130:
  436. + case AR71XX_SOC_AR7141:
  437. + case AR71XX_SOC_AR7161:
  438. + local_irq_save(flags);
  439. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  440. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
  441. + local_irq_restore(flags);
  442. + break;
  443. +
  444. + case AR71XX_SOC_AR7240:
  445. + case AR71XX_SOC_AR7241:
  446. + case AR71XX_SOC_AR7242:
  447. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  448. + local_irq_save(flags);
  449. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  450. + t |= mask;
  451. + t &= ~mask_inv;
  452. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  453. + local_irq_restore(flags);
  454. + break;
  455. +
  456. + case AR71XX_SOC_AR9130:
  457. + case AR71XX_SOC_AR9132:
  458. + local_irq_save(flags);
  459. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  460. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
  461. + local_irq_restore(flags);
  462. + break;
  463. +
  464. + default:
  465. + BUG();
  466. + }
  467. +}
  468. +EXPORT_SYMBOL_GPL(ar71xx_device_stop);
  469. +
  470. +void ar71xx_device_start(u32 mask)
  471. +{
  472. + unsigned long flags;
  473. + u32 mask_inv;
  474. + u32 t;
  475. +
  476. + switch (ar71xx_soc) {
  477. + case AR71XX_SOC_AR7130:
  478. + case AR71XX_SOC_AR7141:
  479. + case AR71XX_SOC_AR7161:
  480. + local_irq_save(flags);
  481. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  482. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
  483. + local_irq_restore(flags);
  484. + break;
  485. +
  486. + case AR71XX_SOC_AR7240:
  487. + case AR71XX_SOC_AR7241:
  488. + case AR71XX_SOC_AR7242:
  489. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  490. + local_irq_save(flags);
  491. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  492. + t &= ~mask;
  493. + t |= mask_inv;
  494. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  495. + local_irq_restore(flags);
  496. + break;
  497. +
  498. + case AR71XX_SOC_AR9130:
  499. + case AR71XX_SOC_AR9132:
  500. + local_irq_save(flags);
  501. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  502. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
  503. + local_irq_restore(flags);
  504. + break;
  505. +
  506. + default:
  507. + BUG();
  508. + }
  509. +}
  510. +EXPORT_SYMBOL_GPL(ar71xx_device_start);
  511. +
  512. +int ar71xx_device_stopped(u32 mask)
  513. +{
  514. + unsigned long flags;
  515. + u32 t;
  516. +
  517. + switch (ar71xx_soc) {
  518. + case AR71XX_SOC_AR7130:
  519. + case AR71XX_SOC_AR7141:
  520. + case AR71XX_SOC_AR7161:
  521. + local_irq_save(flags);
  522. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  523. + local_irq_restore(flags);
  524. + break;
  525. +
  526. + case AR71XX_SOC_AR7240:
  527. + case AR71XX_SOC_AR7241:
  528. + case AR71XX_SOC_AR7242:
  529. + local_irq_save(flags);
  530. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  531. + local_irq_restore(flags);
  532. + break;
  533. +
  534. + case AR71XX_SOC_AR9130:
  535. + case AR71XX_SOC_AR9132:
  536. + local_irq_save(flags);
  537. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  538. + local_irq_restore(flags);
  539. + break;
  540. +
  541. + default:
  542. + BUG();
  543. + }
  544. +
  545. + return ((t & mask) == mask);
  546. +}
  547. +EXPORT_SYMBOL_GPL(ar71xx_device_stopped);
  548. +
  549. +void ar71xx_ddr_flush(u32 reg)
  550. +{
  551. + ar71xx_ddr_wr(reg, 1);
  552. + while ((ar71xx_ddr_rr(reg) & 0x1));
  553. +
  554. + ar71xx_ddr_wr(reg, 1);
  555. + while ((ar71xx_ddr_rr(reg) & 0x1));
  556. +}
  557. +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
  558. +
  559. +void ar71xx_flash_acquire(void)
  560. +{
  561. + mutex_lock(&ar71xx_flash_mutex);
  562. +}
  563. +EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
  564. +
  565. +void ar71xx_flash_release(void)
  566. +{
  567. + mutex_unlock(&ar71xx_flash_mutex);
  568. +}
  569. +EXPORT_SYMBOL_GPL(ar71xx_flash_release);
  570. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.c linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.c
  571. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.c 1970-01-01 01:00:00.000000000 +0100
  572. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.c 2010-12-17 18:34:51.000000000 +0100
  573. @@ -0,0 +1,70 @@
  574. +/*
  575. + * Atheros AP91 reference board ethernet initialization
  576. + *
  577. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  578. + *
  579. + * This program is free software; you can redistribute it and/or modify it
  580. + * under the terms of the GNU General Public License version 2 as published
  581. + * by the Free Software Foundation.
  582. + */
  583. +
  584. +#include "devices.h"
  585. +#include "dev-dsa.h"
  586. +#include "dev-ap91-eth.h"
  587. +
  588. +static struct dsa_chip_data ap91_dsa_chip = {
  589. + .port_names[0] = "cpu",
  590. + .port_names[1] = "lan1",
  591. + .port_names[2] = "lan2",
  592. + .port_names[3] = "lan3",
  593. + .port_names[4] = "lan4",
  594. +};
  595. +
  596. +static struct dsa_platform_data ap91_dsa_data = {
  597. + .nr_chips = 1,
  598. + .chip = &ap91_dsa_chip,
  599. +};
  600. +
  601. +static void ap91_eth_set_port_name(unsigned port, const char *name)
  602. +{
  603. + if (port < 1 || port > 5)
  604. + return;
  605. +
  606. + if (name)
  607. + ap91_dsa_chip.port_names[port] = (char *) name;
  608. +}
  609. +
  610. +void __init ap91_eth_init(u8 *mac_addr, const char *port_names[])
  611. +{
  612. + if (mac_addr)
  613. + ar71xx_set_mac_base(mac_addr);
  614. +
  615. + if (port_names) {
  616. + int i;
  617. +
  618. + for (i = 0; i < AP91_ETH_NUM_PORT_NAMES; i++)
  619. + ap91_eth_set_port_name(i + 1, port_names[i]);
  620. + }
  621. +
  622. + /* WAN port */
  623. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  624. + ar71xx_eth0_data.speed = SPEED_100;
  625. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  626. + ar71xx_eth0_data.fifo_cfg1 = 0x0fff0000;
  627. + ar71xx_eth0_data.fifo_cfg2 = 0x00001fff;
  628. + ar71xx_eth0_data.fifo_cfg3 = 0x008001ff;
  629. +
  630. + /* LAN ports */
  631. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  632. + ar71xx_eth1_data.speed = SPEED_1000;
  633. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  634. + ar71xx_eth1_data.fifo_cfg1 = 0x0fff0000;
  635. + ar71xx_eth1_data.fifo_cfg2 = 0x00001fff;
  636. + ar71xx_eth1_data.fifo_cfg3 = 0x008001ff;
  637. +
  638. + ar71xx_add_device_mdio(0x0);
  639. + ar71xx_add_device_eth(1);
  640. + ar71xx_add_device_eth(0);
  641. +
  642. + ar71xx_add_device_dsa(1, &ap91_dsa_data);
  643. +}
  644. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.h linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.h
  645. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.h 1970-01-01 01:00:00.000000000 +0100
  646. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.h 2010-12-17 18:34:51.000000000 +0100
  647. @@ -0,0 +1,23 @@
  648. +/*
  649. + * Atheros AP91 reference board ethernet initialization
  650. + *
  651. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  652. + *
  653. + * This program is free software; you can redistribute it and/or modify it
  654. + * under the terms of the GNU General Public License version 2 as published
  655. + * by the Free Software Foundation.
  656. + */
  657. +
  658. +#ifndef _AR71XX_DEV_AP91_ETH_H
  659. +#define _AR71XX_DEV_AP91_ETH_H
  660. +
  661. +#define AP91_ETH_NUM_PORT_NAMES 4
  662. +
  663. +#if defined(CONFIG_AR71XX_DEV_AP91_ETH)
  664. +void ap91_eth_init(u8 *mac_addr, const char *port_names[]) __init;
  665. +#else
  666. +static inline void ap91_eth_init(u8 *mac_addr) { }
  667. +#endif
  668. +
  669. +#endif /* _AR71XX_DEV_AP91_ETH_H */
  670. +
  671. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.c
  672. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100
  673. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.c 2010-12-17 18:34:51.000000000 +0100
  674. @@ -0,0 +1,114 @@
  675. +/*
  676. + * Atheros AP91 reference board PCI initialization
  677. + *
  678. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  679. + *
  680. + * This program is free software; you can redistribute it and/or modify it
  681. + * under the terms of the GNU General Public License version 2 as published
  682. + * by the Free Software Foundation.
  683. + */
  684. +
  685. +#include <linux/pci.h>
  686. +#include <linux/ath9k_platform.h>
  687. +#include <linux/delay.h>
  688. +
  689. +#include <asm/mach-ar71xx/ar71xx.h>
  690. +#include <asm/mach-ar71xx/pci.h>
  691. +
  692. +#include "dev-ap91-pci.h"
  693. +
  694. +static struct ath9k_platform_data ap91_wmac_data;
  695. +static char ap91_wmac_mac[6];
  696. +static int ap91_pci_fixup_enabled;
  697. +
  698. +static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
  699. + {
  700. + .slot = 0,
  701. + .pin = 1,
  702. + .irq = AR71XX_PCI_IRQ_DEV0,
  703. + }
  704. +};
  705. +
  706. +static int ap91_pci_plat_dev_init(struct pci_dev *dev)
  707. +{
  708. + switch(PCI_SLOT(dev->devfn)) {
  709. + case 0:
  710. + dev->dev.platform_data = &ap91_wmac_data;
  711. + break;
  712. + }
  713. +
  714. + return 0;
  715. +}
  716. +
  717. +static void ap91_pci_fixup(struct pci_dev *dev)
  718. +{
  719. + void __iomem *mem;
  720. + u16 *cal_data;
  721. + u16 cmd;
  722. + u32 val;
  723. +
  724. + if (!ap91_pci_fixup_enabled)
  725. + return;
  726. +
  727. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  728. +
  729. + cal_data = ap91_wmac_data.eeprom_data;
  730. + if (*cal_data != 0xa55a) {
  731. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  732. + pci_name(dev));
  733. + return;
  734. + }
  735. +
  736. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  737. + if (!mem) {
  738. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  739. + pci_name(dev));
  740. + return;
  741. + }
  742. +
  743. + /* Setup the PCI device to allow access to the internal registers */
  744. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
  745. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  746. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  747. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  748. +
  749. + /* set pointer to first reg address */
  750. + cal_data += 3;
  751. + while (*cal_data != 0xffff) {
  752. + u32 reg;
  753. + reg = *cal_data++;
  754. + val = *cal_data++;
  755. + val |= (*cal_data++) << 16;
  756. +
  757. + __raw_writel(val, mem + reg);
  758. + udelay(100);
  759. + }
  760. +
  761. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  762. + dev->vendor = val & 0xffff;
  763. + dev->device = (val >> 16) & 0xffff;
  764. +
  765. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  766. + dev->revision = val & 0xff;
  767. + dev->class = val >> 8; /* upper 3 bytes */
  768. +
  769. + iounmap(mem);
  770. +}
  771. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup);
  772. +
  773. +void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
  774. +{
  775. + if (cal_data)
  776. + memcpy(ap91_wmac_data.eeprom_data, cal_data,
  777. + sizeof(ap91_wmac_data.eeprom_data));
  778. +
  779. + if (mac_addr) {
  780. + memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac));
  781. + ap91_wmac_data.macaddr = ap91_wmac_mac;
  782. + }
  783. +
  784. + ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
  785. + ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
  786. +
  787. + ap91_pci_fixup_enabled = 1;
  788. +}
  789. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.h
  790. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100
  791. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.h 2010-12-17 18:34:51.000000000 +0100
  792. @@ -0,0 +1,21 @@
  793. +/*
  794. + * Atheros AP91 reference board PCI initialization
  795. + *
  796. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  797. + *
  798. + * This program is free software; you can redistribute it and/or modify it
  799. + * under the terms of the GNU General Public License version 2 as published
  800. + * by the Free Software Foundation.
  801. + */
  802. +
  803. +#ifndef _AR71XX_DEV_AP91_PCI_H
  804. +#define _AR71XX_DEV_AP91_PCI_H
  805. +
  806. +#if defined(CONFIG_AR71XX_DEV_AP91_PCI)
  807. +void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init;
  808. +#else
  809. +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { }
  810. +#endif
  811. +
  812. +#endif /* _AR71XX_DEV_AP91_PCI_H */
  813. +
  814. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.c
  815. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100
  816. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.c 2010-12-17 18:34:51.000000000 +0100
  817. @@ -0,0 +1,159 @@
  818. +/*
  819. + * Atheros AP94 reference board PCI initialization
  820. + *
  821. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  822. + *
  823. + * This program is free software; you can redistribute it and/or modify it
  824. + * under the terms of the GNU General Public License version 2 as published
  825. + * by the Free Software Foundation.
  826. + */
  827. +
  828. +#include <linux/pci.h>
  829. +#include <linux/ath9k_platform.h>
  830. +#include <linux/delay.h>
  831. +
  832. +#include <asm/mach-ar71xx/ar71xx.h>
  833. +#include <asm/mach-ar71xx/pci.h>
  834. +
  835. +#include "dev-ap94-pci.h"
  836. +
  837. +static struct ath9k_platform_data ap94_wmac0_data;
  838. +static struct ath9k_platform_data ap94_wmac1_data;
  839. +static char ap94_wmac0_mac[6];
  840. +static char ap94_wmac1_mac[6];
  841. +static int ap94_pci_fixup_enabled;
  842. +
  843. +static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
  844. + {
  845. + .slot = 0,
  846. + .pin = 1,
  847. + .irq = AR71XX_PCI_IRQ_DEV0,
  848. + }, {
  849. + .slot = 1,
  850. + .pin = 1,
  851. + .irq = AR71XX_PCI_IRQ_DEV1,
  852. + }
  853. +};
  854. +
  855. +static int ap94_pci_plat_dev_init(struct pci_dev *dev)
  856. +{
  857. + switch(PCI_SLOT(dev->devfn)) {
  858. + case 17:
  859. + dev->dev.platform_data = &ap94_wmac0_data;
  860. + break;
  861. +
  862. + case 18:
  863. + dev->dev.platform_data = &ap94_wmac1_data;
  864. + break;
  865. + }
  866. +
  867. + return 0;
  868. +}
  869. +
  870. +static void ap94_pci_fixup(struct pci_dev *dev)
  871. +{
  872. + void __iomem *mem;
  873. + u16 *cal_data;
  874. + u16 cmd;
  875. + u32 bar0;
  876. + u32 val;
  877. +
  878. + if (!ap94_pci_fixup_enabled)
  879. + return;
  880. +
  881. + switch (PCI_SLOT(dev->devfn)) {
  882. + case 17:
  883. + cal_data = ap94_wmac0_data.eeprom_data;
  884. + break;
  885. + case 18:
  886. + cal_data = ap94_wmac1_data.eeprom_data;
  887. + break;
  888. + default:
  889. + return;
  890. + }
  891. +
  892. + if (*cal_data != 0xa55a) {
  893. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  894. + pci_name(dev));
  895. + return;
  896. + }
  897. +
  898. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  899. + if (!mem) {
  900. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  901. + pci_name(dev));
  902. + return;
  903. + }
  904. +
  905. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  906. +
  907. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  908. +
  909. + /* Setup the PCI device to allow access to the internal registers */
  910. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE);
  911. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  912. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  913. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  914. +
  915. + /* set pointer to first reg address */
  916. + cal_data += 3;
  917. + while (*cal_data != 0xffff) {
  918. + u32 reg;
  919. + reg = *cal_data++;
  920. + val = *cal_data++;
  921. + val |= (*cal_data++) << 16;
  922. +
  923. + __raw_writel(val, mem + reg);
  924. + udelay(100);
  925. + }
  926. +
  927. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  928. + dev->vendor = val & 0xffff;
  929. + dev->device = (val >> 16) & 0xffff;
  930. +
  931. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  932. + dev->revision = val & 0xff;
  933. + dev->class = val >> 8; /* upper 3 bytes */
  934. +
  935. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  936. + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
  937. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  938. +
  939. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
  940. +
  941. + iounmap(mem);
  942. +}
  943. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup);
  944. +
  945. +void __init ap94_pci_enable_quirk_wndr3700(void)
  946. +{
  947. + ap94_wmac0_data.quirk_wndr3700 = 1;
  948. + ap94_wmac1_data.quirk_wndr3700 = 1;
  949. +}
  950. +
  951. +void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  952. + u8 *cal_data1, u8 *mac_addr1)
  953. +{
  954. + if (cal_data0)
  955. + memcpy(ap94_wmac0_data.eeprom_data, cal_data0,
  956. + sizeof(ap94_wmac0_data.eeprom_data));
  957. +
  958. + if (cal_data1)
  959. + memcpy(ap94_wmac1_data.eeprom_data, cal_data1,
  960. + sizeof(ap94_wmac1_data.eeprom_data));
  961. +
  962. + if (mac_addr0) {
  963. + memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac));
  964. + ap94_wmac0_data.macaddr = ap94_wmac0_mac;
  965. + }
  966. +
  967. + if (mac_addr1) {
  968. + memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac));
  969. + ap94_wmac1_data.macaddr = ap94_wmac1_mac;
  970. + }
  971. +
  972. + ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
  973. + ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
  974. +
  975. + ap94_pci_fixup_enabled = 1;
  976. +}
  977. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.h
  978. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100
  979. +++ linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.h 2010-12-17 18:34:51.000000000 +0100
  980. @@ -0,0 +1,28 @@
  981. +/*
  982. + * Atheros AP94 reference board PCI initialization
  983. + *
  984. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  985. + *
  986. + * This program is free software; you can redistribute it and/or modify it
  987. + * under the terms of the GNU General Public License version 2 as published
  988. + * by the Free Software Foundation.
  989. + */
  990. +
  991. +#ifndef _AR71XX_DEV_AP94_PCI_H
  992. +#define _AR71XX_DEV_AP94_PCI_H
  993. +
  994. +#if defined(CONFIG_AR71XX_DEV_AP94_PCI)
  995. +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  996. + u8 *cal_data1, u8 *mac_addr1) __init;
  997. +
  998. +void ap94_pci_enable_quirk_wndr3700(void) __init;
  999. +
  1000. +#else
  1001. +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  1002. + u8 *cal_data1, u8 *mac_addr1) {}
  1003. +
  1004. +static inline void ap94_pci_enable_quirk_wndr3700(void) {}
  1005. +#endif
  1006. +
  1007. +#endif /* _AR71XX_DEV_AP94_PCI_H */
  1008. +
  1009. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.c
  1010. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.c 1970-01-01 01:00:00.000000000 +0100
  1011. +++ linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.c 2010-12-17 18:34:51.000000000 +0100
  1012. @@ -0,0 +1,68 @@
  1013. +/*
  1014. + * Atheros AR913x SoC built-in WMAC device support
  1015. + *
  1016. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1017. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1018. + *
  1019. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1020. + *
  1021. + * This program is free software; you can redistribute it and/or modify it
  1022. + * under the terms of the GNU General Public License version 2 as published
  1023. + * by the Free Software Foundation.
  1024. + */
  1025. +
  1026. +#include <linux/kernel.h>
  1027. +#include <linux/init.h>
  1028. +#include <linux/delay.h>
  1029. +#include <linux/etherdevice.h>
  1030. +#include <linux/platform_device.h>
  1031. +#include <linux/ath9k_platform.h>
  1032. +
  1033. +#include <asm/mach-ar71xx/ar71xx.h>
  1034. +
  1035. +#include "dev-ar913x-wmac.h"
  1036. +
  1037. +static struct ath9k_platform_data ar913x_wmac_data;
  1038. +static char ar913x_wmac_mac[6];
  1039. +
  1040. +static struct resource ar913x_wmac_resources[] = {
  1041. + {
  1042. + .start = AR91XX_WMAC_BASE,
  1043. + .end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
  1044. + .flags = IORESOURCE_MEM,
  1045. + }, {
  1046. + .start = AR71XX_CPU_IRQ_IP2,
  1047. + .end = AR71XX_CPU_IRQ_IP2,
  1048. + .flags = IORESOURCE_IRQ,
  1049. + },
  1050. +};
  1051. +
  1052. +static struct platform_device ar913x_wmac_device = {
  1053. + .name = "ath9k",
  1054. + .id = -1,
  1055. + .resource = ar913x_wmac_resources,
  1056. + .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
  1057. + .dev = {
  1058. + .platform_data = &ar913x_wmac_data,
  1059. + },
  1060. +};
  1061. +
  1062. +void __init ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr)
  1063. +{
  1064. + if (cal_data)
  1065. + memcpy(ar913x_wmac_data.eeprom_data, cal_data,
  1066. + sizeof(ar913x_wmac_data.eeprom_data));
  1067. +
  1068. + if (mac_addr) {
  1069. + memcpy(ar913x_wmac_mac, mac_addr, sizeof(ar913x_wmac_mac));
  1070. + ar913x_wmac_data.macaddr = ar913x_wmac_mac;
  1071. + }
  1072. +
  1073. + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
  1074. + mdelay(10);
  1075. +
  1076. + ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
  1077. + mdelay(10);
  1078. +
  1079. + platform_device_register(&ar913x_wmac_device);
  1080. +}
  1081. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.h linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.h
  1082. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.h 1970-01-01 01:00:00.000000000 +0100
  1083. +++ linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.h 2010-12-17 18:34:51.000000000 +0100
  1084. @@ -0,0 +1,19 @@
  1085. +/*
  1086. + * Atheros AR913x SoC built-in WMAC device support
  1087. + *
  1088. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1089. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1090. + *
  1091. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1092. + *
  1093. + * This program is free software; you can redistribute it and/or modify it
  1094. + * under the terms of the GNU General Public License version 2 as published
  1095. + * by the Free Software Foundation.
  1096. + */
  1097. +
  1098. +#ifndef _AR71XX_DEV_AR913X_WMAC_H
  1099. +#define _AR71XX_DEV_AR913X_WMAC_H
  1100. +
  1101. +void ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init;
  1102. +
  1103. +#endif /* _AR71XX_DEV_AR913X_WMAC_H */
  1104. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.36/arch/mips/ar71xx/dev-dsa.c
  1105. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100
  1106. +++ linux-2.6.36/arch/mips/ar71xx/dev-dsa.c 2010-12-17 18:34:51.000000000 +0100
  1107. @@ -0,0 +1,50 @@
  1108. +/*
  1109. + * Atheros AR71xx DSA switch device support
  1110. + *
  1111. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1112. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1113. + *
  1114. + * This program is free software; you can redistribute it and/or modify it
  1115. + * under the terms of the GNU General Public License version 2 as published
  1116. + * by the Free Software Foundation.
  1117. + */
  1118. +
  1119. +#include <linux/init.h>
  1120. +#include <linux/platform_device.h>
  1121. +
  1122. +#include <asm/mach-ar71xx/ar71xx.h>
  1123. +
  1124. +#include "devices.h"
  1125. +#include "dev-dsa.h"
  1126. +
  1127. +static struct platform_device ar71xx_dsa_switch_device = {
  1128. + .name = "dsa",
  1129. + .id = 0,
  1130. +};
  1131. +
  1132. +void __init ar71xx_add_device_dsa(unsigned int id,
  1133. + struct dsa_platform_data *d)
  1134. +{
  1135. + int i;
  1136. +
  1137. + switch (id) {
  1138. + case 0:
  1139. + d->netdev = &ar71xx_eth0_device.dev;
  1140. + break;
  1141. + case 1:
  1142. + d->netdev = &ar71xx_eth1_device.dev;
  1143. + break;
  1144. + default:
  1145. + printk(KERN_ERR
  1146. + "ar71xx: invalid ethernet id %d for DSA switch\n",
  1147. + id);
  1148. + return;
  1149. + }
  1150. +
  1151. + for (i = 0; i < d->nr_chips; i++)
  1152. + d->chip[i].mii_bus = &ar71xx_mdio_device.dev;
  1153. +
  1154. + ar71xx_dsa_switch_device.dev.platform_data = d;
  1155. +
  1156. + platform_device_register(&ar71xx_dsa_switch_device);
  1157. +}
  1158. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.36/arch/mips/ar71xx/dev-dsa.h
  1159. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100
  1160. +++ linux-2.6.36/arch/mips/ar71xx/dev-dsa.h 2010-12-17 18:34:51.000000000 +0100
  1161. @@ -0,0 +1,20 @@
  1162. +/*
  1163. + * Atheros AR71xx DSA switch device support
  1164. + *
  1165. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1166. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1167. + *
  1168. + * This program is free software; you can redistribute it and/or modify it
  1169. + * under the terms of the GNU General Public License version 2 as published
  1170. + * by the Free Software Foundation.
  1171. + */
  1172. +
  1173. +#ifndef _AR71XX_DEV_DSA_H
  1174. +#define _AR71XX_DEV_DSA_H
  1175. +
  1176. +#include <net/dsa.h>
  1177. +
  1178. +void ar71xx_add_device_dsa(unsigned int id,
  1179. + struct dsa_platform_data *d) __init;
  1180. +
  1181. +#endif /* _AR71XX_DEV_DSA_H */
  1182. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.c
  1183. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100
  1184. +++ linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.c 2010-12-17 18:34:51.000000000 +0100
  1185. @@ -0,0 +1,58 @@
  1186. +/*
  1187. + * Atheros AR71xx GPIO button support
  1188. + *
  1189. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1190. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1191. + *
  1192. + * This program is free software; you can redistribute it and/or modify it
  1193. + * under the terms of the GNU General Public License version 2 as published
  1194. + * by the Free Software Foundation.
  1195. + */
  1196. +
  1197. +#include "linux/init.h"
  1198. +#include <linux/platform_device.h>
  1199. +
  1200. +#include "dev-gpio-buttons.h"
  1201. +
  1202. +void __init ar71xx_add_device_gpio_buttons(int id,
  1203. + unsigned poll_interval,
  1204. + unsigned nbuttons,
  1205. + struct gpio_button *buttons)
  1206. +{
  1207. + struct platform_device *pdev;
  1208. + struct gpio_buttons_platform_data pdata;
  1209. + struct gpio_button *p;
  1210. + int err;
  1211. +
  1212. + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
  1213. + if (!p)
  1214. + return;
  1215. +
  1216. + memcpy(p, buttons, nbuttons * sizeof(*p));
  1217. +
  1218. + pdev = platform_device_alloc("gpio-buttons", id);
  1219. + if (!pdev)
  1220. + goto err_free_buttons;
  1221. +
  1222. + memset(&pdata, 0, sizeof(pdata));
  1223. + pdata.poll_interval = poll_interval;
  1224. + pdata.nbuttons = nbuttons;
  1225. + pdata.buttons = p;
  1226. +
  1227. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1228. + if (err)
  1229. + goto err_put_pdev;
  1230. +
  1231. +
  1232. + err = platform_device_add(pdev);
  1233. + if (err)
  1234. + goto err_put_pdev;
  1235. +
  1236. + return;
  1237. +
  1238. +err_put_pdev:
  1239. + platform_device_put(pdev);
  1240. +
  1241. +err_free_buttons:
  1242. + kfree(p);
  1243. +}
  1244. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.h
  1245. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100
  1246. +++ linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.h 2010-12-17 18:34:51.000000000 +0100
  1247. @@ -0,0 +1,25 @@
  1248. +/*
  1249. + * Atheros AR71xx GPIO button support
  1250. + *
  1251. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1252. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1253. + *
  1254. + * This program is free software; you can redistribute it and/or modify it
  1255. + * under the terms of the GNU General Public License version 2 as published
  1256. + * by the Free Software Foundation.
  1257. + */
  1258. +
  1259. +#ifndef _AR71XX_DEV_GPIO_BUTTONS_H
  1260. +#define _AR71XX_DEV_GPIO_BUTTONS_H
  1261. +
  1262. +#include <linux/input.h>
  1263. +#include <linux/gpio_buttons.h>
  1264. +
  1265. +#include <asm/mach-ar71xx/platform.h>
  1266. +
  1267. +void ar71xx_add_device_gpio_buttons(int id,
  1268. + unsigned poll_interval,
  1269. + unsigned nbuttons,
  1270. + struct gpio_button *buttons) __init;
  1271. +
  1272. +#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */
  1273. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.c
  1274. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100
  1275. +++ linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.c 2010-12-17 18:34:51.000000000 +0100
  1276. @@ -0,0 +1,57 @@
  1277. +/*
  1278. + * Atheros AR71xx GPIO LED device support
  1279. + *
  1280. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1281. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1282. + *
  1283. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1284. + *
  1285. + * This program is free software; you can redistribute it and/or modify it
  1286. + * under the terms of the GNU General Public License version 2 as published
  1287. + * by the Free Software Foundation.
  1288. + */
  1289. +
  1290. +#include <linux/init.h>
  1291. +#include <linux/platform_device.h>
  1292. +#include <linux/slab.h>
  1293. +
  1294. +#include "dev-leds-gpio.h"
  1295. +
  1296. +void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
  1297. + struct gpio_led *leds)
  1298. +{
  1299. + struct platform_device *pdev;
  1300. + struct gpio_led_platform_data pdata;
  1301. + struct gpio_led *p;
  1302. + int err;
  1303. +
  1304. + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
  1305. + if (!p)
  1306. + return;
  1307. +
  1308. + memcpy(p, leds, num_leds * sizeof(*p));
  1309. +
  1310. + pdev = platform_device_alloc("leds-gpio", id);
  1311. + if (!pdev)
  1312. + goto err_free_leds;
  1313. +
  1314. + memset(&pdata, 0, sizeof(pdata));
  1315. + pdata.num_leds = num_leds;
  1316. + pdata.leds = p;
  1317. +
  1318. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1319. + if (err)
  1320. + goto err_put_pdev;
  1321. +
  1322. + err = platform_device_add(pdev);
  1323. + if (err)
  1324. + goto err_put_pdev;
  1325. +
  1326. + return;
  1327. +
  1328. +err_put_pdev:
  1329. + platform_device_put(pdev);
  1330. +
  1331. +err_free_leds:
  1332. + kfree(p);
  1333. +}
  1334. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.h
  1335. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100
  1336. +++ linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.h 2010-12-17 18:34:51.000000000 +0100
  1337. @@ -0,0 +1,21 @@
  1338. +/*
  1339. + * Atheros AR71xx GPIO LED device support
  1340. + *
  1341. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1342. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1343. + *
  1344. + * This program is free software; you can redistribute it and/or modify it
  1345. + * under the terms of the GNU General Public License version 2 as published
  1346. + * by the Free Software Foundation.
  1347. + */
  1348. +
  1349. +#ifndef _AR71XX_DEV_LEDS_GPIO_H
  1350. +#define _AR71XX_DEV_LEDS_GPIO_H
  1351. +
  1352. +#include <linux/leds.h>
  1353. +
  1354. +void ar71xx_add_device_leds_gpio(int id,
  1355. + unsigned num_leds,
  1356. + struct gpio_led *leds) __init;
  1357. +
  1358. +#endif /* _AR71XX_DEV_LEDS_GPIO_H */
  1359. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.36/arch/mips/ar71xx/dev-m25p80.c
  1360. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100
  1361. +++ linux-2.6.36/arch/mips/ar71xx/dev-m25p80.c 2010-12-17 18:34:51.000000000 +0100
  1362. @@ -0,0 +1,30 @@
  1363. +/*
  1364. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1365. + *
  1366. + * This program is free software; you can redistribute it and/or modify it
  1367. + * under the terms of the GNU General Public License version 2 as published
  1368. + * by the Free Software Foundation.
  1369. + */
  1370. +
  1371. +#include <linux/init.h>
  1372. +#include <linux/spi/spi.h>
  1373. +#include <linux/spi/flash.h>
  1374. +
  1375. +#include "devices.h"
  1376. +#include "dev-m25p80.h"
  1377. +
  1378. +static struct spi_board_info ar71xx_spi_info[] = {
  1379. + {
  1380. + .bus_num = 0,
  1381. + .chip_select = 0,
  1382. + .max_speed_hz = 25000000,
  1383. + .modalias = "m25p80",
  1384. + }
  1385. +};
  1386. +
  1387. +void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata)
  1388. +{
  1389. + ar71xx_spi_info[0].platform_data = pdata;
  1390. + ar71xx_add_device_spi(NULL, ar71xx_spi_info,
  1391. + ARRAY_SIZE(ar71xx_spi_info));
  1392. +}
  1393. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.36/arch/mips/ar71xx/dev-m25p80.h
  1394. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100
  1395. +++ linux-2.6.36/arch/mips/ar71xx/dev-m25p80.h 2010-12-17 18:34:51.000000000 +0100
  1396. @@ -0,0 +1,16 @@
  1397. +/*
  1398. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1399. + *
  1400. + * This program is free software; you can redistribute it and/or modify it
  1401. + * under the terms of the GNU General Public License version 2 as published
  1402. + * by the Free Software Foundation.
  1403. + */
  1404. +
  1405. +#ifndef _AR71XX_DEV_M25P80_H
  1406. +#define _AR71XX_DEV_M25P80_H
  1407. +
  1408. +#include <linux/spi/flash.h>
  1409. +
  1410. +void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init;
  1411. +
  1412. +#endif /* _AR71XX_DEV_M25P80_H */
  1413. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.c
  1414. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100
  1415. +++ linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.c 2010-12-17 18:34:51.000000000 +0100
  1416. @@ -0,0 +1,40 @@
  1417. +/*
  1418. + * Atheros PB42 reference board PCI initialization
  1419. + *
  1420. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1421. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1422. + *
  1423. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1424. + *
  1425. + * This program is free software; you can redistribute it and/or modify it
  1426. + * under the terms of the GNU General Public License version 2 as published
  1427. + * by the Free Software Foundation.
  1428. + */
  1429. +
  1430. +#include <linux/pci.h>
  1431. +
  1432. +#include <asm/mach-ar71xx/ar71xx.h>
  1433. +#include <asm/mach-ar71xx/pci.h>
  1434. +
  1435. +#include "dev-pb42-pci.h"
  1436. +
  1437. +static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
  1438. + {
  1439. + .slot = 0,
  1440. + .pin = 1,
  1441. + .irq = AR71XX_PCI_IRQ_DEV0,
  1442. + }, {
  1443. + .slot = 1,
  1444. + .pin = 1,
  1445. + .irq = AR71XX_PCI_IRQ_DEV1,
  1446. + }, {
  1447. + .slot = 2,
  1448. + .pin = 1,
  1449. + .irq = AR71XX_PCI_IRQ_DEV2,
  1450. + }
  1451. +};
  1452. +
  1453. +void __init pb42_pci_init(void)
  1454. +{
  1455. + ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
  1456. +}
  1457. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.h
  1458. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100
  1459. +++ linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.h 2010-12-17 18:34:51.000000000 +0100
  1460. @@ -0,0 +1,21 @@
  1461. +/*
  1462. + * Atheros PB42 reference board PCI initialization
  1463. + *
  1464. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1465. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1466. + *
  1467. + * This program is free software; you can redistribute it and/or modify it
  1468. + * under the terms of the GNU General Public License version 2 as published
  1469. + * by the Free Software Foundation.
  1470. + */
  1471. +
  1472. +#ifndef _AR71XX_DEV_PB42_PCI_H
  1473. +#define _AR71XX_DEV_PB42_PCI_H
  1474. +
  1475. +#if defined(CONFIG_AR71XX_DEV_PB42_PCI)
  1476. +void pb42_pci_init(void) __init;
  1477. +#else
  1478. +static inline void pb42_pci_init(void) { }
  1479. +#endif
  1480. +
  1481. +#endif /* _AR71XX_DEV_PB42_PCI_H */
  1482. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.c
  1483. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100
  1484. +++ linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.c 2010-12-17 18:34:51.000000000 +0100
  1485. @@ -0,0 +1,33 @@
  1486. +/*
  1487. + * Atheros PB9x reference board PCI initialization
  1488. + *
  1489. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1490. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1491. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1492. + *
  1493. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1494. + *
  1495. + * This program is free software; you can redistribute it and/or modify it
  1496. + * under the terms of the GNU General Public License version 2 as published
  1497. + * by the Free Software Foundation.
  1498. + */
  1499. +
  1500. +#include <linux/pci.h>
  1501. +
  1502. +#include <asm/mach-ar71xx/ar71xx.h>
  1503. +#include <asm/mach-ar71xx/pci.h>
  1504. +
  1505. +#include "dev-pb9x-pci.h"
  1506. +
  1507. +static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = {
  1508. + {
  1509. + .slot = 0,
  1510. + .pin = 1,
  1511. + .irq = AR71XX_PCI_IRQ_DEV0,
  1512. + }
  1513. +};
  1514. +
  1515. +void __init pb9x_pci_init(void)
  1516. +{
  1517. + ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs);
  1518. +}
  1519. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.h
  1520. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100
  1521. +++ linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.h 2010-12-17 18:34:51.000000000 +0100
  1522. @@ -0,0 +1,22 @@
  1523. +/*
  1524. + * Atheros PB9x reference board PCI initialization
  1525. + *
  1526. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1527. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1528. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1529. + *
  1530. + * This program is free software; you can redistribute it and/or modify it
  1531. + * under the terms of the GNU General Public License version 2 as published
  1532. + * by the Free Software Foundation.
  1533. + */
  1534. +
  1535. +#ifndef _AR71XX_DEV_PB9X_PCI_H
  1536. +#define _AR71XX_DEV_PB9X_PCI_H
  1537. +
  1538. +#if defined(CONFIG_AR71XX_DEV_PB9X_PCI)
  1539. +void pb9x_pci_init(void) __init;
  1540. +#else
  1541. +static inline void pb9x_pci_init(void) { }
  1542. +#endif
  1543. +
  1544. +#endif /* _AR71XX_DEV_PB9X_PCI_H */
  1545. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.36/arch/mips/ar71xx/dev-usb.c
  1546. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100
  1547. +++ linux-2.6.36/arch/mips/ar71xx/dev-usb.c 2010-12-17 18:34:51.000000000 +0100
  1548. @@ -0,0 +1,181 @@
  1549. +/*
  1550. + * Atheros AR71xx USB host device support
  1551. + *
  1552. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1553. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1554. + *
  1555. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1556. + *
  1557. + * This program is free software; you can redistribute it and/or modify it
  1558. + * under the terms of the GNU General Public License version 2 as published
  1559. + * by the Free Software Foundation.
  1560. + */
  1561. +
  1562. +#include <linux/kernel.h>
  1563. +#include <linux/init.h>
  1564. +#include <linux/delay.h>
  1565. +#include <linux/dma-mapping.h>
  1566. +#include <linux/platform_device.h>
  1567. +
  1568. +#include <asm/mach-ar71xx/ar71xx.h>
  1569. +#include <asm/mach-ar71xx/platform.h>
  1570. +
  1571. +#include "dev-usb.h"
  1572. +
  1573. +/*
  1574. + * OHCI (USB full speed host controller)
  1575. + */
  1576. +static struct resource ar71xx_ohci_resources[] = {
  1577. + [0] = {
  1578. + .start = AR71XX_OHCI_BASE,
  1579. + .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
  1580. + .flags = IORESOURCE_MEM,
  1581. + },
  1582. + [1] = {
  1583. + .start = AR71XX_MISC_IRQ_OHCI,
  1584. + .end = AR71XX_MISC_IRQ_OHCI,
  1585. + .flags = IORESOURCE_IRQ,
  1586. + },
  1587. +};
  1588. +
  1589. +static struct resource ar7240_ohci_resources[] = {
  1590. + [0] = {
  1591. + .start = AR7240_OHCI_BASE,
  1592. + .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
  1593. + .flags = IORESOURCE_MEM,
  1594. + },
  1595. + [1] = {
  1596. + .start = AR71XX_CPU_IRQ_USB,
  1597. + .end = AR71XX_CPU_IRQ_USB,
  1598. + .flags = IORESOURCE_IRQ,
  1599. + },
  1600. +};
  1601. +
  1602. +static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
  1603. +static struct platform_device ar71xx_ohci_device = {
  1604. + .name = "ar71xx-ohci",
  1605. + .id = -1,
  1606. + .resource = ar71xx_ohci_resources,
  1607. + .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
  1608. + .dev = {
  1609. + .dma_mask = &ar71xx_ohci_dmamask,
  1610. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1611. + },
  1612. +};
  1613. +
  1614. +/*
  1615. + * EHCI (USB full speed host controller)
  1616. + */
  1617. +static struct resource ar71xx_ehci_resources[] = {
  1618. + [0] = {
  1619. + .start = AR71XX_EHCI_BASE,
  1620. + .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
  1621. + .flags = IORESOURCE_MEM,
  1622. + },
  1623. + [1] = {
  1624. + .start = AR71XX_CPU_IRQ_USB,
  1625. + .end = AR71XX_CPU_IRQ_USB,
  1626. + .flags = IORESOURCE_IRQ,
  1627. + },
  1628. +};
  1629. +
  1630. +static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
  1631. +static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
  1632. +
  1633. +static struct platform_device ar71xx_ehci_device = {
  1634. + .name = "ar71xx-ehci",
  1635. + .id = -1,
  1636. + .resource = ar71xx_ehci_resources,
  1637. + .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
  1638. + .dev = {
  1639. + .dma_mask = &ar71xx_ehci_dmamask,
  1640. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1641. + .platform_data = &ar71xx_ehci_data,
  1642. + },
  1643. +};
  1644. +
  1645. +#define AR71XX_USB_RESET_MASK \
  1646. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
  1647. + | RESET_MODULE_USB_OHCI_DLL)
  1648. +
  1649. +#define AR7240_USB_RESET_MASK \
  1650. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
  1651. +
  1652. +static void __init ar71xx_usb_setup(void)
  1653. +{
  1654. + ar71xx_device_stop(AR71XX_USB_RESET_MASK);
  1655. + mdelay(1000);
  1656. + ar71xx_device_start(AR71XX_USB_RESET_MASK);
  1657. +
  1658. + /* Turning on the Buff and Desc swap bits */
  1659. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
  1660. +
  1661. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1662. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
  1663. +
  1664. + mdelay(900);
  1665. +
  1666. + platform_device_register(&ar71xx_ohci_device);
  1667. + platform_device_register(&ar71xx_ehci_device);
  1668. +}
  1669. +
  1670. +static void __init ar7240_usb_setup(void)
  1671. +{
  1672. + ar71xx_device_stop(AR7240_USB_RESET_MASK);
  1673. + mdelay(1000);
  1674. + ar71xx_device_start(AR7240_USB_RESET_MASK);
  1675. +
  1676. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1677. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
  1678. +
  1679. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  1680. + ar71xx_ehci_data.is_ar91xx = 1;
  1681. + ar71xx_ehci_device.resource = ar7240_ohci_resources;
  1682. + ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1683. + platform_device_register(&ar71xx_ehci_device);
  1684. + } else {
  1685. + ar71xx_ohci_device.resource = ar7240_ohci_resources;
  1686. + ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1687. + platform_device_register(&ar71xx_ohci_device);
  1688. + }
  1689. +}
  1690. +
  1691. +static void __init ar91xx_usb_setup(void)
  1692. +{
  1693. + ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
  1694. + mdelay(10);
  1695. +
  1696. + ar71xx_device_start(RESET_MODULE_USB_HOST);
  1697. + mdelay(10);
  1698. +
  1699. + ar71xx_device_start(RESET_MODULE_USB_PHY);
  1700. + mdelay(10);
  1701. +
  1702. + ar71xx_ehci_data.is_ar91xx = 1;
  1703. + platform_device_register(&ar71xx_ehci_device);
  1704. +}
  1705. +
  1706. +void __init ar71xx_add_device_usb(void)
  1707. +{
  1708. + switch (ar71xx_soc) {
  1709. + case AR71XX_SOC_AR7240:
  1710. + case AR71XX_SOC_AR7241:
  1711. + case AR71XX_SOC_AR7242:
  1712. + ar7240_usb_setup();
  1713. + break;
  1714. +
  1715. + case AR71XX_SOC_AR7130:
  1716. + case AR71XX_SOC_AR7141:
  1717. + case AR71XX_SOC_AR7161:
  1718. + ar71xx_usb_setup();
  1719. + break;
  1720. +
  1721. + case AR71XX_SOC_AR9130:
  1722. + case AR71XX_SOC_AR9132:
  1723. + ar91xx_usb_setup();
  1724. + break;
  1725. +
  1726. + default:
  1727. + BUG();
  1728. + }
  1729. +}
  1730. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.36/arch/mips/ar71xx/dev-usb.h
  1731. --- linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100
  1732. +++ linux-2.6.36/arch/mips/ar71xx/dev-usb.h 2010-12-17 18:34:51.000000000 +0100
  1733. @@ -0,0 +1,17 @@
  1734. +/*
  1735. + * Atheros AR71xx USB host device support
  1736. + *
  1737. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1738. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  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. +#ifndef _AR71XX_DEV_USB_H
  1746. +#define _AR71XX_DEV_USB_H
  1747. +
  1748. +void ar71xx_add_device_usb(void) __init;
  1749. +
  1750. +#endif /* _AR71XX_DEV_USB_H */
  1751. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/devices.c linux-2.6.36/arch/mips/ar71xx/devices.c
  1752. --- linux-2.6.36.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100
  1753. +++ linux-2.6.36/arch/mips/ar71xx/devices.c 2010-12-17 18:34:51.000000000 +0100
  1754. @@ -0,0 +1,575 @@
  1755. +/*
  1756. + * Atheros AR71xx SoC platform devices
  1757. + *
  1758. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1759. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1760. + *
  1761. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1762. + *
  1763. + * This program is free software; you can redistribute it and/or modify it
  1764. + * under the terms of the GNU General Public License version 2 as published
  1765. + * by the Free Software Foundation.
  1766. + */
  1767. +
  1768. +#include <linux/kernel.h>
  1769. +#include <linux/init.h>
  1770. +#include <linux/delay.h>
  1771. +#include <linux/etherdevice.h>
  1772. +#include <linux/platform_device.h>
  1773. +#include <linux/serial_8250.h>
  1774. +
  1775. +#include <asm/mach-ar71xx/ar71xx.h>
  1776. +
  1777. +#include "devices.h"
  1778. +
  1779. +static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
  1780. +
  1781. +static struct resource ar71xx_uart_resources[] = {
  1782. + {
  1783. + .start = AR71XX_UART_BASE,
  1784. + .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
  1785. + .flags = IORESOURCE_MEM,
  1786. + },
  1787. +};
  1788. +
  1789. +#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
  1790. +static struct plat_serial8250_port ar71xx_uart_data[] = {
  1791. + {
  1792. + .mapbase = AR71XX_UART_BASE,
  1793. + .irq = AR71XX_MISC_IRQ_UART,
  1794. + .flags = AR71XX_UART_FLAGS,
  1795. + .iotype = UPIO_MEM32,
  1796. + .regshift = 2,
  1797. + }, {
  1798. + /* terminating entry */
  1799. + }
  1800. +};
  1801. +
  1802. +static struct platform_device ar71xx_uart_device = {
  1803. + .name = "serial8250",
  1804. + .id = PLAT8250_DEV_PLATFORM,
  1805. + .resource = ar71xx_uart_resources,
  1806. + .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
  1807. + .dev = {
  1808. + .platform_data = ar71xx_uart_data
  1809. + },
  1810. +};
  1811. +
  1812. +void __init ar71xx_add_device_uart(void)
  1813. +{
  1814. + ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
  1815. + platform_device_register(&ar71xx_uart_device);
  1816. +}
  1817. +
  1818. +static struct resource ar71xx_mdio_resources[] = {
  1819. + {
  1820. + .name = "mdio_base",
  1821. + .flags = IORESOURCE_MEM,
  1822. + .start = AR71XX_GE0_BASE,
  1823. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1824. + }
  1825. +};
  1826. +
  1827. +static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
  1828. +
  1829. +struct platform_device ar71xx_mdio_device = {
  1830. + .name = "ag71xx-mdio",
  1831. + .id = -1,
  1832. + .resource = ar71xx_mdio_resources,
  1833. + .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
  1834. + .dev = {
  1835. + .platform_data = &ar71xx_mdio_data,
  1836. + },
  1837. +};
  1838. +
  1839. +void __init ar71xx_add_device_mdio(u32 phy_mask)
  1840. +{
  1841. + switch (ar71xx_soc) {
  1842. + case AR71XX_SOC_AR7240:
  1843. + case AR71XX_SOC_AR7241:
  1844. + case AR71XX_SOC_AR7242:
  1845. + ar71xx_mdio_data.is_ar7240 = 1;
  1846. + break;
  1847. + default:
  1848. + break;
  1849. + }
  1850. +
  1851. + ar71xx_mdio_data.phy_mask = phy_mask;
  1852. +
  1853. + platform_device_register(&ar71xx_mdio_device);
  1854. +}
  1855. +
  1856. +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
  1857. +{
  1858. + void __iomem *base;
  1859. + u32 t;
  1860. +
  1861. + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
  1862. +
  1863. + t = __raw_readl(base + cfg_reg);
  1864. + t &= ~(3 << shift);
  1865. + t |= (2 << shift);
  1866. + __raw_writel(t, base + cfg_reg);
  1867. + udelay(100);
  1868. +
  1869. + __raw_writel(pll_val, base + pll_reg);
  1870. +
  1871. + t |= (3 << shift);
  1872. + __raw_writel(t, base + cfg_reg);
  1873. + udelay(100);
  1874. +
  1875. + t &= ~(3 << shift);
  1876. + __raw_writel(t, base + cfg_reg);
  1877. + udelay(100);
  1878. +
  1879. + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
  1880. + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
  1881. +
  1882. + iounmap(base);
  1883. +}
  1884. +
  1885. +struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  1886. +struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  1887. +
  1888. +static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
  1889. +{
  1890. + struct ar71xx_eth_pll_data *pll_data;
  1891. + u32 pll_val;
  1892. +
  1893. + switch (mac) {
  1894. + case 0:
  1895. + pll_data = &ar71xx_eth0_pll_data;
  1896. + break;
  1897. + case 1:
  1898. + pll_data = &ar71xx_eth1_pll_data;
  1899. + break;
  1900. + default:
  1901. + BUG();
  1902. + }
  1903. +
  1904. + switch (speed) {
  1905. + case SPEED_10:
  1906. + pll_val = pll_data->pll_10;
  1907. + break;
  1908. + case SPEED_100:
  1909. + pll_val = pll_data->pll_100;
  1910. + break;
  1911. + case SPEED_1000:
  1912. + pll_val = pll_data->pll_1000;
  1913. + break;
  1914. + default:
  1915. + BUG();
  1916. + }
  1917. +
  1918. + return pll_val;
  1919. +}
  1920. +
  1921. +static void ar71xx_set_pll_ge0(int speed)
  1922. +{
  1923. + u32 val = ar71xx_get_eth_pll(0, speed);
  1924. +
  1925. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
  1926. + val, AR71XX_ETH0_PLL_SHIFT);
  1927. +}
  1928. +
  1929. +static void ar71xx_set_pll_ge1(int speed)
  1930. +{
  1931. + u32 val = ar71xx_get_eth_pll(1, speed);
  1932. +
  1933. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
  1934. + val, AR71XX_ETH1_PLL_SHIFT);
  1935. +}
  1936. +
  1937. +static void ar724x_set_pll_ge0(int speed)
  1938. +{
  1939. + /* TODO */
  1940. +}
  1941. +
  1942. +static void ar724x_set_pll_ge1(int speed)
  1943. +{
  1944. + /* TODO */
  1945. +}
  1946. +
  1947. +static void ar91xx_set_pll_ge0(int speed)
  1948. +{
  1949. + u32 val = ar71xx_get_eth_pll(0, speed);
  1950. +
  1951. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
  1952. + val, AR91XX_ETH0_PLL_SHIFT);
  1953. +}
  1954. +
  1955. +static void ar91xx_set_pll_ge1(int speed)
  1956. +{
  1957. + u32 val = ar71xx_get_eth_pll(1, speed);
  1958. +
  1959. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
  1960. + val, AR91XX_ETH1_PLL_SHIFT);
  1961. +}
  1962. +
  1963. +static void ar71xx_ddr_flush_ge0(void)
  1964. +{
  1965. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
  1966. +}
  1967. +
  1968. +static void ar71xx_ddr_flush_ge1(void)
  1969. +{
  1970. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
  1971. +}
  1972. +
  1973. +static void ar724x_ddr_flush_ge0(void)
  1974. +{
  1975. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
  1976. +}
  1977. +
  1978. +static void ar724x_ddr_flush_ge1(void)
  1979. +{
  1980. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
  1981. +}
  1982. +
  1983. +static void ar91xx_ddr_flush_ge0(void)
  1984. +{
  1985. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
  1986. +}
  1987. +
  1988. +static void ar91xx_ddr_flush_ge1(void)
  1989. +{
  1990. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
  1991. +}
  1992. +
  1993. +static struct resource ar71xx_eth0_resources[] = {
  1994. + {
  1995. + .name = "mac_base",
  1996. + .flags = IORESOURCE_MEM,
  1997. + .start = AR71XX_GE0_BASE,
  1998. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1999. + }, {
  2000. + .name = "mii_ctrl",
  2001. + .flags = IORESOURCE_MEM,
  2002. + .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
  2003. + .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
  2004. + }, {
  2005. + .name = "mac_irq",
  2006. + .flags = IORESOURCE_IRQ,
  2007. + .start = AR71XX_CPU_IRQ_GE0,
  2008. + .end = AR71XX_CPU_IRQ_GE0,
  2009. + },
  2010. +};
  2011. +
  2012. +struct ag71xx_platform_data ar71xx_eth0_data = {
  2013. + .reset_bit = RESET_MODULE_GE0_MAC,
  2014. +};
  2015. +
  2016. +struct platform_device ar71xx_eth0_device = {
  2017. + .name = "ag71xx",
  2018. + .id = 0,
  2019. + .resource = ar71xx_eth0_resources,
  2020. + .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
  2021. + .dev = {
  2022. + .platform_data = &ar71xx_eth0_data,
  2023. + },
  2024. +};
  2025. +
  2026. +static struct resource ar71xx_eth1_resources[] = {
  2027. + {
  2028. + .name = "mac_base",
  2029. + .flags = IORESOURCE_MEM,
  2030. + .start = AR71XX_GE1_BASE,
  2031. + .end = AR71XX_GE1_BASE + 0x200 - 1,
  2032. + }, {
  2033. + .name = "mii_ctrl",
  2034. + .flags = IORESOURCE_MEM,
  2035. + .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
  2036. + .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
  2037. + }, {
  2038. + .name = "mac_irq",
  2039. + .flags = IORESOURCE_IRQ,
  2040. + .start = AR71XX_CPU_IRQ_GE1,
  2041. + .end = AR71XX_CPU_IRQ_GE1,
  2042. + },
  2043. +};
  2044. +
  2045. +struct ag71xx_platform_data ar71xx_eth1_data = {
  2046. + .reset_bit = RESET_MODULE_GE1_MAC,
  2047. +};
  2048. +
  2049. +struct platform_device ar71xx_eth1_device = {
  2050. + .name = "ag71xx",
  2051. + .id = 1,
  2052. + .resource = ar71xx_eth1_resources,
  2053. + .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
  2054. + .dev = {
  2055. + .platform_data = &ar71xx_eth1_data,
  2056. + },
  2057. +};
  2058. +
  2059. +#define AR71XX_PLL_VAL_1000 0x00110000
  2060. +#define AR71XX_PLL_VAL_100 0x00001099
  2061. +#define AR71XX_PLL_VAL_10 0x00991099
  2062. +
  2063. +#define AR724X_PLL_VAL_1000 0x00110000
  2064. +#define AR724X_PLL_VAL_100 0x00001099
  2065. +#define AR724X_PLL_VAL_10 0x00991099
  2066. +
  2067. +#define AR91XX_PLL_VAL_1000 0x1a000000
  2068. +#define AR91XX_PLL_VAL_100 0x13000a44
  2069. +#define AR91XX_PLL_VAL_10 0x00441099
  2070. +
  2071. +static void __init ar71xx_init_eth_pll_data(unsigned int id)
  2072. +{
  2073. + struct ar71xx_eth_pll_data *pll_data;
  2074. + u32 pll_10, pll_100, pll_1000;
  2075. +
  2076. + switch (id) {
  2077. + case 0:
  2078. + pll_data = &ar71xx_eth0_pll_data;
  2079. + break;
  2080. + case 1:
  2081. + pll_data = &ar71xx_eth1_pll_data;
  2082. + break;
  2083. + default:
  2084. + BUG();
  2085. + }
  2086. +
  2087. + switch (ar71xx_soc) {
  2088. + case AR71XX_SOC_AR7130:
  2089. + case AR71XX_SOC_AR7141:
  2090. + case AR71XX_SOC_AR7161:
  2091. + pll_10 = AR71XX_PLL_VAL_10;
  2092. + pll_100 = AR71XX_PLL_VAL_100;
  2093. + pll_1000 = AR71XX_PLL_VAL_1000;
  2094. + break;
  2095. +
  2096. + case AR71XX_SOC_AR7240:
  2097. + case AR71XX_SOC_AR7241:
  2098. + case AR71XX_SOC_AR7242:
  2099. + pll_10 = AR724X_PLL_VAL_10;
  2100. + pll_100 = AR724X_PLL_VAL_100;
  2101. + pll_1000 = AR724X_PLL_VAL_1000;
  2102. + break;
  2103. +
  2104. + case AR71XX_SOC_AR9130:
  2105. + case AR71XX_SOC_AR9132:
  2106. + pll_10 = AR91XX_PLL_VAL_10;
  2107. + pll_100 = AR91XX_PLL_VAL_100;
  2108. + pll_1000 = AR91XX_PLL_VAL_1000;
  2109. + break;
  2110. + default:
  2111. + BUG();
  2112. + }
  2113. +
  2114. + if (!pll_data->pll_10)
  2115. + pll_data->pll_10 = pll_10;
  2116. +
  2117. + if (!pll_data->pll_100)
  2118. + pll_data->pll_100 = pll_100;
  2119. +
  2120. + if (!pll_data->pll_1000)
  2121. + pll_data->pll_1000 = pll_1000;
  2122. +}
  2123. +
  2124. +static int ar71xx_eth_instance __initdata;
  2125. +void __init ar71xx_add_device_eth(unsigned int id)
  2126. +{
  2127. + struct platform_device *pdev;
  2128. + struct ag71xx_platform_data *pdata;
  2129. +
  2130. + ar71xx_init_eth_pll_data(id);
  2131. +
  2132. + switch (id) {
  2133. + case 0:
  2134. + switch (ar71xx_eth0_data.phy_if_mode) {
  2135. + case PHY_INTERFACE_MODE_MII:
  2136. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
  2137. + break;
  2138. + case PHY_INTERFACE_MODE_GMII:
  2139. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
  2140. + break;
  2141. + case PHY_INTERFACE_MODE_RGMII:
  2142. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
  2143. + break;
  2144. + case PHY_INTERFACE_MODE_RMII:
  2145. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
  2146. + break;
  2147. + default:
  2148. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2149. + "for eth0\n");
  2150. + return;
  2151. + }
  2152. + pdev = &ar71xx_eth0_device;
  2153. + break;
  2154. + case 1:
  2155. + switch (ar71xx_eth1_data.phy_if_mode) {
  2156. + case PHY_INTERFACE_MODE_RMII:
  2157. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
  2158. + break;
  2159. + case PHY_INTERFACE_MODE_RGMII:
  2160. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
  2161. + break;
  2162. + default:
  2163. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2164. + "for eth1\n");
  2165. + return;
  2166. + }
  2167. + pdev = &ar71xx_eth1_device;
  2168. + break;
  2169. + default:
  2170. + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
  2171. + return;
  2172. + }
  2173. +
  2174. + pdata = pdev->dev.platform_data;
  2175. +
  2176. + switch (ar71xx_soc) {
  2177. + case AR71XX_SOC_AR7130:
  2178. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2179. + : ar71xx_ddr_flush_ge0;
  2180. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2181. + : ar71xx_set_pll_ge0;
  2182. + break;
  2183. +
  2184. + case AR71XX_SOC_AR7141:
  2185. + case AR71XX_SOC_AR7161:
  2186. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2187. + : ar71xx_ddr_flush_ge0;
  2188. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2189. + : ar71xx_set_pll_ge0;
  2190. + pdata->has_gbit = 1;
  2191. + break;
  2192. +
  2193. + case AR71XX_SOC_AR7241:
  2194. + case AR71XX_SOC_AR7242:
  2195. + ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
  2196. + ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
  2197. + /* fall through */
  2198. + case AR71XX_SOC_AR7240:
  2199. + pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
  2200. + : ar724x_ddr_flush_ge0;
  2201. + pdata->set_pll = id ? ar724x_set_pll_ge1
  2202. + : ar724x_set_pll_ge0;
  2203. + pdata->is_ar724x = 1;
  2204. + break;
  2205. +
  2206. + case AR71XX_SOC_AR9130:
  2207. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2208. + : ar91xx_ddr_flush_ge0;
  2209. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2210. + : ar91xx_set_pll_ge0;
  2211. + pdata->is_ar91xx = 1;
  2212. + break;
  2213. +
  2214. + case AR71XX_SOC_AR9132:
  2215. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2216. + : ar91xx_ddr_flush_ge0;
  2217. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2218. + : ar91xx_set_pll_ge0;
  2219. + pdata->is_ar91xx = 1;
  2220. + pdata->has_gbit = 1;
  2221. + break;
  2222. +
  2223. + default:
  2224. + BUG();
  2225. + }
  2226. +
  2227. + switch (pdata->phy_if_mode) {
  2228. + case PHY_INTERFACE_MODE_GMII:
  2229. + case PHY_INTERFACE_MODE_RGMII:
  2230. + if (!pdata->has_gbit) {
  2231. + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
  2232. + id);
  2233. + return;
  2234. + }
  2235. + /* fallthrough */
  2236. + default:
  2237. + break;
  2238. + }
  2239. +
  2240. + if (is_valid_ether_addr(ar71xx_mac_base)) {
  2241. + memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
  2242. + pdata->mac_addr[5] += ar71xx_eth_instance;
  2243. + } else {
  2244. + random_ether_addr(pdata->mac_addr);
  2245. + printk(KERN_DEBUG
  2246. + "ar71xx: using random MAC address for eth%d\n",
  2247. + ar71xx_eth_instance);
  2248. + }
  2249. +
  2250. + if (pdata->mii_bus_dev == NULL)
  2251. + pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
  2252. +
  2253. + /* Reset the device */
  2254. + ar71xx_device_stop(pdata->reset_bit);
  2255. + mdelay(100);
  2256. +
  2257. + ar71xx_device_start(pdata->reset_bit);
  2258. + mdelay(100);
  2259. +
  2260. + platform_device_register(pdev);
  2261. + ar71xx_eth_instance++;
  2262. +}
  2263. +
  2264. +static struct resource ar71xx_spi_resources[] = {
  2265. + [0] = {
  2266. + .start = AR71XX_SPI_BASE,
  2267. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  2268. + .flags = IORESOURCE_MEM,
  2269. + },
  2270. +};
  2271. +
  2272. +static struct platform_device ar71xx_spi_device = {
  2273. + .name = "ar71xx-spi",
  2274. + .id = -1,
  2275. + .resource = ar71xx_spi_resources,
  2276. + .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
  2277. +};
  2278. +
  2279. +void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2280. + struct spi_board_info const *info,
  2281. + unsigned n)
  2282. +{
  2283. + spi_register_board_info(info, n);
  2284. + ar71xx_spi_device.dev.platform_data = pdata;
  2285. + platform_device_register(&ar71xx_spi_device);
  2286. +}
  2287. +
  2288. +void __init ar71xx_add_device_wdt(void)
  2289. +{
  2290. + platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
  2291. +}
  2292. +
  2293. +void __init ar71xx_set_mac_base(unsigned char *mac)
  2294. +{
  2295. + memcpy(ar71xx_mac_base, mac, ETH_ALEN);
  2296. +}
  2297. +
  2298. +void __init ar71xx_parse_mac_addr(char *mac_str)
  2299. +{
  2300. + u8 tmp[ETH_ALEN];
  2301. + int t;
  2302. +
  2303. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  2304. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2305. +
  2306. + if (t != ETH_ALEN)
  2307. + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
  2308. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2309. +
  2310. + if (t == ETH_ALEN)
  2311. + ar71xx_set_mac_base(tmp);
  2312. + else
  2313. + printk(KERN_DEBUG "ar71xx: failed to parse mac address "
  2314. + "\"%s\"\n", mac_str);
  2315. +}
  2316. +
  2317. +static int __init ar71xx_ethaddr_setup(char *str)
  2318. +{
  2319. + ar71xx_parse_mac_addr(str);
  2320. + return 1;
  2321. +}
  2322. +__setup("ethaddr=", ar71xx_ethaddr_setup);
  2323. +
  2324. +static int __init ar71xx_kmac_setup(char *str)
  2325. +{
  2326. + ar71xx_parse_mac_addr(str);
  2327. + return 1;
  2328. +}
  2329. +__setup("kmac=", ar71xx_kmac_setup);
  2330. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/devices.h linux-2.6.36/arch/mips/ar71xx/devices.h
  2331. --- linux-2.6.36.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100
  2332. +++ linux-2.6.36/arch/mips/ar71xx/devices.h 2010-12-17 18:34:51.000000000 +0100
  2333. @@ -0,0 +1,48 @@
  2334. +/*
  2335. + * Atheros AR71xx SoC device definitions
  2336. + *
  2337. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2338. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2339. + *
  2340. + * This program is free software; you can redistribute it and/or modify it
  2341. + * under the terms of the GNU General Public License version 2 as published
  2342. + * by the Free Software Foundation.
  2343. + */
  2344. +
  2345. +#ifndef __AR71XX_DEVICES_H
  2346. +#define __AR71XX_DEVICES_H
  2347. +
  2348. +#include <asm/mach-ar71xx/platform.h>
  2349. +
  2350. +struct platform_device;
  2351. +
  2352. +void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2353. + struct spi_board_info const *info,
  2354. + unsigned n) __init;
  2355. +
  2356. +void ar71xx_set_mac_base(unsigned char *mac) __init;
  2357. +void ar71xx_parse_mac_addr(char *mac_str) __init;
  2358. +
  2359. +struct ar71xx_eth_pll_data {
  2360. + u32 pll_10;
  2361. + u32 pll_100;
  2362. + u32 pll_1000;
  2363. +};
  2364. +
  2365. +extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  2366. +extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  2367. +
  2368. +extern struct ag71xx_platform_data ar71xx_eth0_data;
  2369. +extern struct ag71xx_platform_data ar71xx_eth1_data;
  2370. +extern struct platform_device ar71xx_eth0_device;
  2371. +extern struct platform_device ar71xx_eth1_device;
  2372. +void ar71xx_add_device_eth(unsigned int id) __init;
  2373. +
  2374. +extern struct platform_device ar71xx_mdio_device;
  2375. +void ar71xx_add_device_mdio(u32 phy_mask) __init;
  2376. +
  2377. +void ar71xx_add_device_uart(void) __init;
  2378. +
  2379. +void ar71xx_add_device_wdt(void) __init;
  2380. +
  2381. +#endif /* __AR71XX_DEVICES_H */
  2382. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/early_printk.c linux-2.6.36/arch/mips/ar71xx/early_printk.c
  2383. --- linux-2.6.36.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100
  2384. +++ linux-2.6.36/arch/mips/ar71xx/early_printk.c 2010-12-17 18:34:51.000000000 +0100
  2385. @@ -0,0 +1,30 @@
  2386. +/*
  2387. + * Atheros AR71xx SoC early printk support
  2388. + *
  2389. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2390. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2391. + *
  2392. + * This program is free software; you can redistribute it and/or modify it
  2393. + * under the terms of the GNU General Public License version 2 as published
  2394. + * by the Free Software Foundation.
  2395. + */
  2396. +
  2397. +#include <linux/io.h>
  2398. +#include <linux/serial_reg.h>
  2399. +#include <asm/addrspace.h>
  2400. +
  2401. +#include <asm/mach-ar71xx/ar71xx.h>
  2402. +
  2403. +#define UART_READ(r) \
  2404. + __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r)))
  2405. +
  2406. +#define UART_WRITE(r, v) \
  2407. + __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r)))
  2408. +
  2409. +void prom_putchar(unsigned char ch)
  2410. +{
  2411. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2412. + UART_WRITE(UART_TX, ch);
  2413. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2414. +}
  2415. +
  2416. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/gpio.c linux-2.6.36/arch/mips/ar71xx/gpio.c
  2417. --- linux-2.6.36.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
  2418. +++ linux-2.6.36/arch/mips/ar71xx/gpio.c 2010-12-17 18:34:51.000000000 +0100
  2419. @@ -0,0 +1,182 @@
  2420. +/*
  2421. + * Atheros AR71xx SoC GPIO API support
  2422. + *
  2423. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2424. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2425. + *
  2426. + * This program is free software; you can redistribute it and/or modify it
  2427. + * under the terms of the GNU General Public License version 2 as published
  2428. + * by the Free Software Foundation.
  2429. + */
  2430. +
  2431. +#include <linux/kernel.h>
  2432. +#include <linux/init.h>
  2433. +#include <linux/module.h>
  2434. +#include <linux/types.h>
  2435. +#include <linux/spinlock.h>
  2436. +#include <linux/io.h>
  2437. +#include <linux/ioport.h>
  2438. +#include <linux/gpio.h>
  2439. +
  2440. +#include <asm/mach-ar71xx/ar71xx.h>
  2441. +
  2442. +static DEFINE_SPINLOCK(ar71xx_gpio_lock);
  2443. +
  2444. +unsigned long ar71xx_gpio_count;
  2445. +EXPORT_SYMBOL(ar71xx_gpio_count);
  2446. +
  2447. +void __ar71xx_gpio_set_value(unsigned gpio, int value)
  2448. +{
  2449. + void __iomem *base = ar71xx_gpio_base;
  2450. +
  2451. + if (value)
  2452. + __raw_writel(1 << gpio, base + GPIO_REG_SET);
  2453. + else
  2454. + __raw_writel(1 << gpio, base + GPIO_REG_CLEAR);
  2455. +}
  2456. +EXPORT_SYMBOL(__ar71xx_gpio_set_value);
  2457. +
  2458. +int __ar71xx_gpio_get_value(unsigned gpio)
  2459. +{
  2460. + return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1;
  2461. +}
  2462. +EXPORT_SYMBOL(__ar71xx_gpio_get_value);
  2463. +
  2464. +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  2465. +{
  2466. + return __ar71xx_gpio_get_value(offset);
  2467. +}
  2468. +
  2469. +static void ar71xx_gpio_set_value(struct gpio_chip *chip,
  2470. + unsigned offset, int value)
  2471. +{
  2472. + __ar71xx_gpio_set_value(offset, value);
  2473. +}
  2474. +
  2475. +static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
  2476. + unsigned offset)
  2477. +{
  2478. + void __iomem *base = ar71xx_gpio_base;
  2479. + unsigned long flags;
  2480. +
  2481. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2482. +
  2483. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset),
  2484. + base + GPIO_REG_OE);
  2485. +
  2486. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2487. +
  2488. + return 0;
  2489. +}
  2490. +
  2491. +static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
  2492. + unsigned offset, int value)
  2493. +{
  2494. + void __iomem *base = ar71xx_gpio_base;
  2495. + unsigned long flags;
  2496. +
  2497. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2498. +
  2499. + if (value)
  2500. + __raw_writel(1 << offset, base + GPIO_REG_SET);
  2501. + else
  2502. + __raw_writel(1 << offset, base + GPIO_REG_CLEAR);
  2503. +
  2504. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset),
  2505. + base + GPIO_REG_OE);
  2506. +
  2507. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2508. +
  2509. + return 0;
  2510. +}
  2511. +
  2512. +static struct gpio_chip ar71xx_gpio_chip = {
  2513. + .label = "ar71xx",
  2514. + .get = ar71xx_gpio_get_value,
  2515. + .set = ar71xx_gpio_set_value,
  2516. + .direction_input = ar71xx_gpio_direction_input,
  2517. + .direction_output = ar71xx_gpio_direction_output,
  2518. + .base = 0,
  2519. + .ngpio = AR71XX_GPIO_COUNT,
  2520. +};
  2521. +
  2522. +void ar71xx_gpio_function_enable(u32 mask)
  2523. +{
  2524. + void __iomem *base = ar71xx_gpio_base;
  2525. + unsigned long flags;
  2526. +
  2527. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2528. +
  2529. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask,
  2530. + base + GPIO_REG_FUNC);
  2531. + /* flush write */
  2532. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2533. +
  2534. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2535. +}
  2536. +
  2537. +void ar71xx_gpio_function_disable(u32 mask)
  2538. +{
  2539. + void __iomem *base = ar71xx_gpio_base;
  2540. + unsigned long flags;
  2541. +
  2542. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2543. +
  2544. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask,
  2545. + base + GPIO_REG_FUNC);
  2546. + /* flush write */
  2547. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2548. +
  2549. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2550. +}
  2551. +
  2552. +void ar71xx_gpio_function_setup(u32 set, u32 clear)
  2553. +{
  2554. + void __iomem *base = ar71xx_gpio_base;
  2555. + unsigned long flags;
  2556. +
  2557. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2558. +
  2559. + __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set,
  2560. + base + GPIO_REG_FUNC);
  2561. + /* flush write */
  2562. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2563. +
  2564. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2565. +}
  2566. +EXPORT_SYMBOL(ar71xx_gpio_function_setup);
  2567. +
  2568. +void __init ar71xx_gpio_init(void)
  2569. +{
  2570. + int err;
  2571. +
  2572. + if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
  2573. + "AR71xx GPIO controller"))
  2574. + panic("cannot allocate AR71xx GPIO registers page");
  2575. +
  2576. + switch (ar71xx_soc) {
  2577. + case AR71XX_SOC_AR7130:
  2578. + case AR71XX_SOC_AR7141:
  2579. + case AR71XX_SOC_AR7161:
  2580. + ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
  2581. + break;
  2582. +
  2583. + case AR71XX_SOC_AR7240:
  2584. + case AR71XX_SOC_AR7241:
  2585. + case AR71XX_SOC_AR7242:
  2586. + ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT;
  2587. + break;
  2588. +
  2589. + case AR71XX_SOC_AR9130:
  2590. + case AR71XX_SOC_AR9132:
  2591. + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
  2592. + break;
  2593. +
  2594. + default:
  2595. + BUG();
  2596. + }
  2597. +
  2598. + err = gpiochip_add(&ar71xx_gpio_chip);
  2599. + if (err)
  2600. + panic("cannot add AR71xx GPIO chip, error=%d", err);
  2601. +}
  2602. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/irq.c linux-2.6.36/arch/mips/ar71xx/irq.c
  2603. --- linux-2.6.36.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100
  2604. +++ linux-2.6.36/arch/mips/ar71xx/irq.c 2010-12-17 18:34:51.000000000 +0100
  2605. @@ -0,0 +1,295 @@
  2606. +/*
  2607. + * Atheros AR71xx SoC specific interrupt handling
  2608. + *
  2609. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2610. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2611. + *
  2612. + * Parts of this file are based on Atheros' 2.6.15 BSP
  2613. + *
  2614. + * This program is free software; you can redistribute it and/or modify it
  2615. + * under the terms of the GNU General Public License version 2 as published
  2616. + * by the Free Software Foundation.
  2617. + */
  2618. +
  2619. +#include <linux/kernel.h>
  2620. +#include <linux/init.h>
  2621. +#include <linux/interrupt.h>
  2622. +#include <linux/irq.h>
  2623. +
  2624. +#include <asm/irq_cpu.h>
  2625. +#include <asm/mipsregs.h>
  2626. +
  2627. +#include <asm/mach-ar71xx/ar71xx.h>
  2628. +
  2629. +static int ip2_flush_reg;
  2630. +
  2631. +static void ar71xx_gpio_irq_dispatch(void)
  2632. +{
  2633. + void __iomem *base = ar71xx_gpio_base;
  2634. + u32 pending;
  2635. +
  2636. + pending = __raw_readl(base + GPIO_REG_INT_PENDING) &
  2637. + __raw_readl(base + GPIO_REG_INT_ENABLE);
  2638. +
  2639. + if (pending)
  2640. + do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
  2641. + else
  2642. + spurious_interrupt();
  2643. +}
  2644. +
  2645. +static void ar71xx_gpio_irq_unmask(unsigned int irq)
  2646. +{
  2647. + void __iomem *base = ar71xx_gpio_base;
  2648. + u32 t;
  2649. +
  2650. + irq -= AR71XX_GPIO_IRQ_BASE;
  2651. +
  2652. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2653. + __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE);
  2654. +
  2655. + /* flush write */
  2656. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2657. +}
  2658. +
  2659. +static void ar71xx_gpio_irq_mask(unsigned int irq)
  2660. +{
  2661. + void __iomem *base = ar71xx_gpio_base;
  2662. + u32 t;
  2663. +
  2664. + irq -= AR71XX_GPIO_IRQ_BASE;
  2665. +
  2666. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2667. + __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE);
  2668. +
  2669. + /* flush write */
  2670. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2671. +}
  2672. +
  2673. +#if 0
  2674. +static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
  2675. +{
  2676. + /* TODO: implement */
  2677. + return 0;
  2678. +}
  2679. +#else
  2680. +#define ar71xx_gpio_irq_set_type NULL
  2681. +#endif
  2682. +
  2683. +static struct irq_chip ar71xx_gpio_irq_chip = {
  2684. + .name = "AR71XX GPIO",
  2685. + .unmask = ar71xx_gpio_irq_unmask,
  2686. + .mask = ar71xx_gpio_irq_mask,
  2687. + .mask_ack = ar71xx_gpio_irq_mask,
  2688. + .set_type = ar71xx_gpio_irq_set_type,
  2689. +};
  2690. +
  2691. +static struct irqaction ar71xx_gpio_irqaction = {
  2692. + .handler = no_action,
  2693. + .name = "cascade [AR71XX GPIO]",
  2694. +};
  2695. +
  2696. +#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED)
  2697. +#define GPIO_INT_ALL 0xffff
  2698. +
  2699. +static void __init ar71xx_gpio_irq_init(void)
  2700. +{
  2701. + void __iomem *base = ar71xx_gpio_base;
  2702. + int i;
  2703. +
  2704. + __raw_writel(0, base + GPIO_REG_INT_ENABLE);
  2705. + __raw_writel(0, base + GPIO_REG_INT_PENDING);
  2706. +
  2707. + /* setup type of all GPIO interrupts to level sensitive */
  2708. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE);
  2709. +
  2710. + /* setup polarity of all GPIO interrupts to active high */
  2711. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY);
  2712. +
  2713. + for (i = AR71XX_GPIO_IRQ_BASE;
  2714. + i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) {
  2715. + irq_desc[i].status = GPIO_IRQ_INIT_STATUS;
  2716. + set_irq_chip_and_handler(i, &ar71xx_gpio_irq_chip,
  2717. + handle_level_irq);
  2718. + }
  2719. +
  2720. + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
  2721. +}
  2722. +
  2723. +static void ar71xx_misc_irq_dispatch(void)
  2724. +{
  2725. + u32 pending;
  2726. +
  2727. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
  2728. + & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
  2729. +
  2730. + if (pending & MISC_INT_UART)
  2731. + do_IRQ(AR71XX_MISC_IRQ_UART);
  2732. +
  2733. + else if (pending & MISC_INT_DMA)
  2734. + do_IRQ(AR71XX_MISC_IRQ_DMA);
  2735. +
  2736. + else if (pending & MISC_INT_PERFC)
  2737. + do_IRQ(AR71XX_MISC_IRQ_PERFC);
  2738. +
  2739. + else if (pending & MISC_INT_TIMER)
  2740. + do_IRQ(AR71XX_MISC_IRQ_TIMER);
  2741. +
  2742. + else if (pending & MISC_INT_OHCI)
  2743. + do_IRQ(AR71XX_MISC_IRQ_OHCI);
  2744. +
  2745. + else if (pending & MISC_INT_ERROR)
  2746. + do_IRQ(AR71XX_MISC_IRQ_ERROR);
  2747. +
  2748. + else if (pending & MISC_INT_GPIO)
  2749. + ar71xx_gpio_irq_dispatch();
  2750. +
  2751. + else if (pending & MISC_INT_WDOG)
  2752. + do_IRQ(AR71XX_MISC_IRQ_WDOG);
  2753. +
  2754. + else
  2755. + spurious_interrupt();
  2756. +}
  2757. +
  2758. +static void ar71xx_misc_irq_unmask(unsigned int irq)
  2759. +{
  2760. + void __iomem *base = ar71xx_reset_base;
  2761. + u32 t;
  2762. +
  2763. + irq -= AR71XX_MISC_IRQ_BASE;
  2764. +
  2765. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2766. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2767. +
  2768. + /* flush write */
  2769. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2770. +}
  2771. +
  2772. +static void ar71xx_misc_irq_mask(unsigned int irq)
  2773. +{
  2774. + void __iomem *base = ar71xx_reset_base;
  2775. + u32 t;
  2776. +
  2777. + irq -= AR71XX_MISC_IRQ_BASE;
  2778. +
  2779. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2780. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2781. +
  2782. + /* flush write */
  2783. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2784. +}
  2785. +
  2786. +static void ar724x_misc_irq_ack(unsigned int irq)
  2787. +{
  2788. + void __iomem *base = ar71xx_reset_base;
  2789. + u32 t;
  2790. +
  2791. + irq -= AR71XX_MISC_IRQ_BASE;
  2792. +
  2793. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2794. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2795. +
  2796. + /* flush write */
  2797. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2798. +}
  2799. +
  2800. +static struct irq_chip ar71xx_misc_irq_chip = {
  2801. + .name = "AR71XX MISC",
  2802. + .unmask = ar71xx_misc_irq_unmask,
  2803. + .mask = ar71xx_misc_irq_mask,
  2804. +};
  2805. +
  2806. +static struct irqaction ar71xx_misc_irqaction = {
  2807. + .handler = no_action,
  2808. + .name = "cascade [AR71XX MISC]",
  2809. +};
  2810. +
  2811. +static void __init ar71xx_misc_irq_init(void)
  2812. +{
  2813. + void __iomem *base = ar71xx_reset_base;
  2814. + int i;
  2815. +
  2816. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2817. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2818. +
  2819. + switch (ar71xx_soc) {
  2820. + case AR71XX_SOC_AR7240:
  2821. + case AR71XX_SOC_AR7241:
  2822. + case AR71XX_SOC_AR7242:
  2823. + ar71xx_misc_irq_chip.ack = ar724x_misc_irq_ack;
  2824. + break;
  2825. + default:
  2826. + ar71xx_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
  2827. + break;
  2828. + }
  2829. +
  2830. + for (i = AR71XX_MISC_IRQ_BASE;
  2831. + i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) {
  2832. + irq_desc[i].status = IRQ_DISABLED;
  2833. + set_irq_chip_and_handler(i, &ar71xx_misc_irq_chip,
  2834. + handle_level_irq);
  2835. + }
  2836. +
  2837. + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
  2838. +}
  2839. +
  2840. +asmlinkage void plat_irq_dispatch(void)
  2841. +{
  2842. + unsigned long pending;
  2843. +
  2844. + pending = read_c0_status() & read_c0_cause() & ST0_IM;
  2845. +
  2846. + if (pending & STATUSF_IP7)
  2847. + do_IRQ(AR71XX_CPU_IRQ_TIMER);
  2848. +
  2849. + else if (pending & STATUSF_IP2) {
  2850. + /*
  2851. + * This IRQ is meant for a PCI device. Drivers for PCI devices
  2852. + * typically allocate coherent DMA memory for the descriptor
  2853. + * ring, however the DMA controller may still have some
  2854. + * unsynchronized data in the FIFO.
  2855. + * Issue a flush here to ensure that the driver sees the update.
  2856. + */
  2857. + ar71xx_ddr_flush(ip2_flush_reg);
  2858. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  2859. + }
  2860. +
  2861. + else if (pending & STATUSF_IP4)
  2862. + do_IRQ(AR71XX_CPU_IRQ_GE0);
  2863. +
  2864. + else if (pending & STATUSF_IP5)
  2865. + do_IRQ(AR71XX_CPU_IRQ_GE1);
  2866. +
  2867. + else if (pending & STATUSF_IP3)
  2868. + do_IRQ(AR71XX_CPU_IRQ_USB);
  2869. +
  2870. + else if (pending & STATUSF_IP6)
  2871. + ar71xx_misc_irq_dispatch();
  2872. +
  2873. + else
  2874. + spurious_interrupt();
  2875. +}
  2876. +
  2877. +void __init arch_init_irq(void)
  2878. +{
  2879. + switch(ar71xx_soc) {
  2880. + case AR71XX_SOC_AR7240:
  2881. + case AR71XX_SOC_AR7241:
  2882. + case AR71XX_SOC_AR7242:
  2883. + ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
  2884. + break;
  2885. + case AR71XX_SOC_AR9130:
  2886. + case AR71XX_SOC_AR9132:
  2887. + ip2_flush_reg = AR91XX_DDR_REG_FLUSH_WMAC;
  2888. + break;
  2889. + default:
  2890. + ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
  2891. + break;
  2892. + }
  2893. + mips_cpu_irq_init();
  2894. +
  2895. + ar71xx_misc_irq_init();
  2896. +
  2897. + cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC;
  2898. +
  2899. + ar71xx_gpio_irq_init();
  2900. +}
  2901. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.36/arch/mips/ar71xx/mach-ap81.c
  2902. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100
  2903. +++ linux-2.6.36/arch/mips/ar71xx/mach-ap81.c 2010-12-17 18:34:51.000000000 +0100
  2904. @@ -0,0 +1,140 @@
  2905. +/*
  2906. + * Atheros AP81 board support
  2907. + *
  2908. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  2909. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  2910. + *
  2911. + * This program is free software; you can redistribute it and/or modify it
  2912. + * under the terms of the GNU General Public License version 2 as published
  2913. + * by the Free Software Foundation.
  2914. + */
  2915. +
  2916. +#include <linux/mtd/mtd.h>
  2917. +#include <linux/mtd/partitions.h>
  2918. +
  2919. +#include <asm/mach-ar71xx/ar71xx.h>
  2920. +
  2921. +#include "machtype.h"
  2922. +#include "devices.h"
  2923. +#include "dev-m25p80.h"
  2924. +#include "dev-ar913x-wmac.h"
  2925. +#include "dev-gpio-buttons.h"
  2926. +#include "dev-leds-gpio.h"
  2927. +#include "dev-usb.h"
  2928. +
  2929. +#define AP81_GPIO_LED_STATUS 1
  2930. +#define AP81_GPIO_LED_AOSS 3
  2931. +#define AP81_GPIO_LED_WLAN 6
  2932. +#define AP81_GPIO_LED_POWER 14
  2933. +
  2934. +#define AP81_GPIO_BTN_SW4 12
  2935. +#define AP81_GPIO_BTN_SW1 21
  2936. +
  2937. +#define AP81_BUTTONS_POLL_INTERVAL 20
  2938. +
  2939. +#ifdef CONFIG_MTD_PARTITIONS
  2940. +static struct mtd_partition ap81_partitions[] = {
  2941. + {
  2942. + .name = "u-boot",
  2943. + .offset = 0,
  2944. + .size = 0x040000,
  2945. + .mask_flags = MTD_WRITEABLE,
  2946. + } , {
  2947. + .name = "u-boot-env",
  2948. + .offset = 0x040000,
  2949. + .size = 0x010000,
  2950. + } , {
  2951. + .name = "rootfs",
  2952. + .offset = 0x050000,
  2953. + .size = 0x500000,
  2954. + } , {
  2955. + .name = "uImage",
  2956. + .offset = 0x550000,
  2957. + .size = 0x100000,
  2958. + } , {
  2959. + .name = "ART",
  2960. + .offset = 0x650000,
  2961. + .size = 0x1b0000,
  2962. + .mask_flags = MTD_WRITEABLE,
  2963. + }
  2964. +};
  2965. +#endif /* CONFIG_MTD_PARTITIONS */
  2966. +
  2967. +static struct flash_platform_data ap81_flash_data = {
  2968. +#ifdef CONFIG_MTD_PARTITIONS
  2969. + .parts = ap81_partitions,
  2970. + .nr_parts = ARRAY_SIZE(ap81_partitions),
  2971. +#endif
  2972. +};
  2973. +
  2974. +static struct gpio_led ap81_leds_gpio[] __initdata = {
  2975. + {
  2976. + .name = "ap81:green:status",
  2977. + .gpio = AP81_GPIO_LED_STATUS,
  2978. + .active_low = 1,
  2979. + }, {
  2980. + .name = "ap81:amber:aoss",
  2981. + .gpio = AP81_GPIO_LED_AOSS,
  2982. + .active_low = 1,
  2983. + }, {
  2984. + .name = "ap81:green:wlan",
  2985. + .gpio = AP81_GPIO_LED_WLAN,
  2986. + .active_low = 1,
  2987. + }, {
  2988. + .name = "ap81:green:power",
  2989. + .gpio = AP81_GPIO_LED_POWER,
  2990. + .active_low = 1,
  2991. + }
  2992. +};
  2993. +
  2994. +static struct gpio_button ap81_gpio_buttons[] __initdata = {
  2995. + {
  2996. + .desc = "sw1",
  2997. + .type = EV_KEY,
  2998. + .code = BTN_0,
  2999. + .threshold = 3,
  3000. + .gpio = AP81_GPIO_BTN_SW1,
  3001. + .active_low = 1,
  3002. + } , {
  3003. + .desc = "sw4",
  3004. + .type = EV_KEY,
  3005. + .code = BTN_1,
  3006. + .threshold = 3,
  3007. + .gpio = AP81_GPIO_BTN_SW4,
  3008. + .active_low = 1,
  3009. + }
  3010. +};
  3011. +
  3012. +static void __init ap81_setup(void)
  3013. +{
  3014. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3015. +
  3016. + ar71xx_set_mac_base(eeprom);
  3017. + ar71xx_add_device_mdio(0x0);
  3018. +
  3019. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3020. + ar71xx_eth0_data.speed = SPEED_100;
  3021. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3022. + ar71xx_eth0_data.has_ar8216 = 1;
  3023. +
  3024. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3025. + ar71xx_eth1_data.phy_mask = 0x10;
  3026. +
  3027. + ar71xx_add_device_eth(0);
  3028. + ar71xx_add_device_eth(1);
  3029. +
  3030. + ar71xx_add_device_usb();
  3031. +
  3032. + ar71xx_add_device_m25p80(&ap81_flash_data);
  3033. +
  3034. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
  3035. + ap81_leds_gpio);
  3036. +
  3037. + ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL,
  3038. + ARRAY_SIZE(ap81_gpio_buttons),
  3039. + ap81_gpio_buttons);
  3040. +
  3041. + ar913x_add_device_wmac(eeprom, NULL);
  3042. +}
  3043. +
  3044. +MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup);
  3045. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.36/arch/mips/ar71xx/mach-ap83.c
  3046. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100
  3047. +++ linux-2.6.36/arch/mips/ar71xx/mach-ap83.c 2010-12-17 18:34:51.000000000 +0100
  3048. @@ -0,0 +1,266 @@
  3049. +/*
  3050. + * Atheros AP83 board support
  3051. + *
  3052. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3053. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3054. + *
  3055. + * This program is free software; you can redistribute it and/or modify it
  3056. + * under the terms of the GNU General Public License version 2 as published
  3057. + * by the Free Software Foundation.
  3058. + */
  3059. +
  3060. +#include <linux/delay.h>
  3061. +#include <linux/platform_device.h>
  3062. +#include <linux/mtd/mtd.h>
  3063. +#include <linux/mtd/partitions.h>
  3064. +#include <linux/spi/spi.h>
  3065. +#include <linux/spi/spi_gpio.h>
  3066. +#include <linux/spi/vsc7385.h>
  3067. +
  3068. +#include <asm/mach-ar71xx/ar71xx.h>
  3069. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  3070. +
  3071. +#include "machtype.h"
  3072. +#include "devices.h"
  3073. +#include "dev-ar913x-wmac.h"
  3074. +#include "dev-gpio-buttons.h"
  3075. +#include "dev-leds-gpio.h"
  3076. +#include "dev-usb.h"
  3077. +
  3078. +#define AP83_GPIO_LED_WLAN 6
  3079. +#define AP83_GPIO_LED_POWER 14
  3080. +#define AP83_GPIO_LED_JUMPSTART 15
  3081. +#define AP83_GPIO_BTN_JUMPSTART 12
  3082. +#define AP83_GPIO_BTN_RESET 21
  3083. +
  3084. +#define AP83_050_GPIO_VSC7385_CS 1
  3085. +#define AP83_050_GPIO_VSC7385_MISO 3
  3086. +#define AP83_050_GPIO_VSC7385_MOSI 16
  3087. +#define AP83_050_GPIO_VSC7385_SCK 17
  3088. +
  3089. +#define AP83_BUTTONS_POLL_INTERVAL 20
  3090. +
  3091. +#ifdef CONFIG_MTD_PARTITIONS
  3092. +static struct mtd_partition ap83_flash_partitions[] = {
  3093. + {
  3094. + .name = "u-boot",
  3095. + .offset = 0,
  3096. + .size = 0x040000,
  3097. + .mask_flags = MTD_WRITEABLE,
  3098. + } , {
  3099. + .name = "u-boot-env",
  3100. + .offset = 0x040000,
  3101. + .size = 0x020000,
  3102. + .mask_flags = MTD_WRITEABLE,
  3103. + } , {
  3104. + .name = "kernel",
  3105. + .offset = 0x060000,
  3106. + .size = 0x140000,
  3107. + } , {
  3108. + .name = "rootfs",
  3109. + .offset = 0x1a0000,
  3110. + .size = 0x650000,
  3111. + } , {
  3112. + .name = "art",
  3113. + .offset = 0x7f0000,
  3114. + .size = 0x010000,
  3115. + .mask_flags = MTD_WRITEABLE,
  3116. + } , {
  3117. + .name = "firmware",
  3118. + .offset = 0x060000,
  3119. + .size = 0x790000,
  3120. + }
  3121. +};
  3122. +#endif /* CONFIG_MTD_PARTITIONS */
  3123. +
  3124. +static struct ar91xx_flash_platform_data ap83_flash_data = {
  3125. + .width = 2,
  3126. +#ifdef CONFIG_MTD_PARTITIONS
  3127. + .parts = ap83_flash_partitions,
  3128. + .nr_parts = ARRAY_SIZE(ap83_flash_partitions),
  3129. +#endif
  3130. +};
  3131. +
  3132. +static struct resource ap83_flash_resources[] = {
  3133. + [0] = {
  3134. + .start = AR71XX_SPI_BASE,
  3135. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3136. + .flags = IORESOURCE_MEM,
  3137. + },
  3138. +};
  3139. +
  3140. +static struct platform_device ap83_flash_device = {
  3141. + .name = "ar91xx-flash",
  3142. + .id = -1,
  3143. + .resource = ap83_flash_resources,
  3144. + .num_resources = ARRAY_SIZE(ap83_flash_resources),
  3145. + .dev = {
  3146. + .platform_data = &ap83_flash_data,
  3147. + }
  3148. +};
  3149. +
  3150. +static struct gpio_led ap83_leds_gpio[] __initdata = {
  3151. + {
  3152. + .name = "ap83:green:jumpstart",
  3153. + .gpio = AP83_GPIO_LED_JUMPSTART,
  3154. + .active_low = 0,
  3155. + }, {
  3156. + .name = "ap83:green:power",
  3157. + .gpio = AP83_GPIO_LED_POWER,
  3158. + .active_low = 0,
  3159. + }, {
  3160. + .name = "ap83:green:wlan",
  3161. + .gpio = AP83_GPIO_LED_WLAN,
  3162. + .active_low = 0,
  3163. + },
  3164. +};
  3165. +
  3166. +static struct gpio_button ap83_gpio_buttons[] __initdata = {
  3167. + {
  3168. + .desc = "soft_reset",
  3169. + .type = EV_KEY,
  3170. + .code = KEY_RESTART,
  3171. + .threshold = 3,
  3172. + .gpio = AP83_GPIO_BTN_RESET,
  3173. + .active_low = 1,
  3174. + } , {
  3175. + .desc = "jumpstart",
  3176. + .type = EV_KEY,
  3177. + .code = KEY_WPS_BUTTON,
  3178. + .threshold = 3,
  3179. + .gpio = AP83_GPIO_BTN_JUMPSTART,
  3180. + .active_low = 1,
  3181. + }
  3182. +};
  3183. +
  3184. +static struct resource ap83_040_spi_resources[] = {
  3185. + [0] = {
  3186. + .start = AR71XX_SPI_BASE,
  3187. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3188. + .flags = IORESOURCE_MEM,
  3189. + },
  3190. +};
  3191. +
  3192. +static struct platform_device ap83_040_spi_device = {
  3193. + .name = "ap83-spi",
  3194. + .id = 0,
  3195. + .resource = ap83_040_spi_resources,
  3196. + .num_resources = ARRAY_SIZE(ap83_040_spi_resources),
  3197. +};
  3198. +
  3199. +static struct spi_gpio_platform_data ap83_050_spi_data = {
  3200. + .miso = AP83_050_GPIO_VSC7385_MISO,
  3201. + .mosi = AP83_050_GPIO_VSC7385_MOSI,
  3202. + .sck = AP83_050_GPIO_VSC7385_SCK,
  3203. + .num_chipselect = 1,
  3204. +};
  3205. +
  3206. +static struct platform_device ap83_050_spi_device = {
  3207. + .name = "spi_gpio",
  3208. + .id = 0,
  3209. + .dev = {
  3210. + .platform_data = &ap83_050_spi_data,
  3211. + }
  3212. +};
  3213. +
  3214. +static void ap83_vsc7385_reset(void)
  3215. +{
  3216. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  3217. + udelay(10);
  3218. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  3219. + mdelay(50);
  3220. +}
  3221. +
  3222. +static struct vsc7385_platform_data ap83_vsc7385_data = {
  3223. + .reset = ap83_vsc7385_reset,
  3224. + .ucode_name = "vsc7385_ucode_ap83.bin",
  3225. + .mac_cfg = {
  3226. + .tx_ipg = 6,
  3227. + .bit2 = 0,
  3228. + .clk_sel = 3,
  3229. + },
  3230. +};
  3231. +
  3232. +static struct spi_board_info ap83_spi_info[] = {
  3233. + {
  3234. + .bus_num = 0,
  3235. + .chip_select = 0,
  3236. + .max_speed_hz = 25000000,
  3237. + .modalias = "spi-vsc7385",
  3238. + .platform_data = &ap83_vsc7385_data,
  3239. + .controller_data = (void *) AP83_050_GPIO_VSC7385_CS,
  3240. + }
  3241. +};
  3242. +
  3243. +static void __init ap83_generic_setup(void)
  3244. +{
  3245. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3246. +
  3247. + ar71xx_set_mac_base(eeprom);
  3248. +
  3249. + ar71xx_add_device_mdio(0xfffffffe);
  3250. +
  3251. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3252. + ar71xx_eth0_data.phy_mask = 0x1;
  3253. +
  3254. + ar71xx_add_device_eth(0);
  3255. +
  3256. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3257. + ar71xx_eth1_data.speed = SPEED_1000;
  3258. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  3259. +
  3260. + ar71xx_eth1_pll_data.pll_1000 = 0x1f000000;
  3261. +
  3262. + ar71xx_add_device_eth(1);
  3263. +
  3264. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
  3265. + ap83_leds_gpio);
  3266. +
  3267. + ar71xx_add_device_gpio_buttons(-1, AP83_BUTTONS_POLL_INTERVAL,
  3268. + ARRAY_SIZE(ap83_gpio_buttons),
  3269. + ap83_gpio_buttons);
  3270. +
  3271. + ar71xx_add_device_usb();
  3272. +
  3273. + ar913x_add_device_wmac(eeprom, NULL);
  3274. +
  3275. + platform_device_register(&ap83_flash_device);
  3276. +
  3277. + spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info));
  3278. +}
  3279. +
  3280. +static void __init ap83_040_setup(void)
  3281. +{
  3282. + ap83_flash_data.is_shared=1;
  3283. + ap83_generic_setup();
  3284. + platform_device_register(&ap83_040_spi_device);
  3285. +}
  3286. +
  3287. +static void __init ap83_050_setup(void)
  3288. +{
  3289. + ap83_generic_setup();
  3290. + platform_device_register(&ap83_050_spi_device);
  3291. +}
  3292. +
  3293. +static void __init ap83_setup(void)
  3294. +{
  3295. + u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244);
  3296. + unsigned int board_version;
  3297. +
  3298. + board_version = (unsigned int)(board_id[0] - '0');
  3299. + board_version += ((unsigned int)(board_id[1] - '0')) * 10;
  3300. +
  3301. + switch (board_version) {
  3302. + case 40:
  3303. + ap83_040_setup();
  3304. + break;
  3305. + case 50:
  3306. + ap83_050_setup();
  3307. + break;
  3308. + default:
  3309. + printk(KERN_WARNING "AP83-%03u board is not yet supported\n",
  3310. + board_version);
  3311. + }
  3312. +}
  3313. +
  3314. +MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup);
  3315. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.36/arch/mips/ar71xx/mach-aw-nr580.c
  3316. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100
  3317. +++ linux-2.6.36/arch/mips/ar71xx/mach-aw-nr580.c 2010-12-17 18:34:51.000000000 +0100
  3318. @@ -0,0 +1,101 @@
  3319. +/*
  3320. + * AzureWave AW-NR580 board support
  3321. + *
  3322. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3323. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3324. + *
  3325. + * This program is free software; you can redistribute it and/or modify it
  3326. + * under the terms of the GNU General Public License version 2 as published
  3327. + * by the Free Software Foundation.
  3328. + */
  3329. +
  3330. +#include <linux/mtd/mtd.h>
  3331. +#include <linux/mtd/partitions.h>
  3332. +
  3333. +#include <asm/mips_machine.h>
  3334. +#include <asm/mach-ar71xx/ar71xx.h>
  3335. +
  3336. +#include "machtype.h"
  3337. +#include "devices.h"
  3338. +#include "dev-m25p80.h"
  3339. +#include "dev-gpio-buttons.h"
  3340. +#include "dev-pb42-pci.h"
  3341. +#include "dev-leds-gpio.h"
  3342. +
  3343. +#define AW_NR580_GPIO_LED_READY_RED 0
  3344. +#define AW_NR580_GPIO_LED_WLAN 1
  3345. +#define AW_NR580_GPIO_LED_READY_GREEN 2
  3346. +#define AW_NR580_GPIO_LED_WPS_GREEN 4
  3347. +#define AW_NR580_GPIO_LED_WPS_AMBER 5
  3348. +
  3349. +#define AW_NR580_GPIO_BTN_WPS 3
  3350. +#define AW_NR580_GPIO_BTN_RESET 11
  3351. +
  3352. +#define AW_NR580_BUTTONS_POLL_INTERVAL 20
  3353. +
  3354. +static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
  3355. + {
  3356. + .name = "aw-nr580:red:ready",
  3357. + .gpio = AW_NR580_GPIO_LED_READY_RED,
  3358. + .active_low = 0,
  3359. + }, {
  3360. + .name = "aw-nr580:green:ready",
  3361. + .gpio = AW_NR580_GPIO_LED_READY_GREEN,
  3362. + .active_low = 0,
  3363. + }, {
  3364. + .name = "aw-nr580:green:wps",
  3365. + .gpio = AW_NR580_GPIO_LED_WPS_GREEN,
  3366. + .active_low = 0,
  3367. + }, {
  3368. + .name = "aw-nr580:amber:wps",
  3369. + .gpio = AW_NR580_GPIO_LED_WPS_AMBER,
  3370. + .active_low = 0,
  3371. + }, {
  3372. + .name = "aw-nr580:green:wlan",
  3373. + .gpio = AW_NR580_GPIO_LED_WLAN,
  3374. + .active_low = 0,
  3375. + }
  3376. +};
  3377. +
  3378. +static struct gpio_button aw_nr580_gpio_buttons[] __initdata = {
  3379. + {
  3380. + .desc = "reset",
  3381. + .type = EV_KEY,
  3382. + .code = KEY_RESTART,
  3383. + .threshold = 3,
  3384. + .gpio = AW_NR580_GPIO_BTN_RESET,
  3385. + .active_low = 1,
  3386. + }, {
  3387. + .desc = "wps",
  3388. + .type = EV_KEY,
  3389. + .code = KEY_WPS_BUTTON,
  3390. + .threshold = 3,
  3391. + .gpio = AW_NR580_GPIO_BTN_WPS,
  3392. + .active_low = 1,
  3393. + }
  3394. +};
  3395. +
  3396. +static void __init aw_nr580_setup(void)
  3397. +{
  3398. + ar71xx_add_device_mdio(0x0);
  3399. +
  3400. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  3401. + ar71xx_eth0_data.speed = SPEED_100;
  3402. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3403. +
  3404. + ar71xx_add_device_eth(0);
  3405. +
  3406. + pb42_pci_init();
  3407. +
  3408. + ar71xx_add_device_m25p80(NULL);
  3409. +
  3410. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
  3411. + aw_nr580_leds_gpio);
  3412. +
  3413. + ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL,
  3414. + ARRAY_SIZE(aw_nr580_gpio_buttons),
  3415. + aw_nr580_gpio_buttons);
  3416. +}
  3417. +
  3418. +MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580",
  3419. + aw_nr580_setup);
  3420. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.36/arch/mips/ar71xx/mach-dir-600-a1.c
  3421. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100
  3422. +++ linux-2.6.36/arch/mips/ar71xx/mach-dir-600-a1.c 2010-12-17 18:34:51.000000000 +0100
  3423. @@ -0,0 +1,138 @@
  3424. +/*
  3425. + * D-Link DIR-600 rev. A1 board support
  3426. + *
  3427. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  3428. + *
  3429. + * This program is free software; you can redistribute it and/or modify it
  3430. + * under the terms of the GNU General Public License version 2 as published
  3431. + * by the Free Software Foundation.
  3432. + */
  3433. +
  3434. +#include <linux/mtd/mtd.h>
  3435. +#include <linux/mtd/partitions.h>
  3436. +
  3437. +#include <asm/mach-ar71xx/ar71xx.h>
  3438. +
  3439. +#include "machtype.h"
  3440. +#include "devices.h"
  3441. +#include "dev-m25p80.h"
  3442. +#include "dev-ap91-eth.h"
  3443. +#include "dev-ap91-pci.h"
  3444. +#include "dev-gpio-buttons.h"
  3445. +#include "dev-leds-gpio.h"
  3446. +#include "nvram.h"
  3447. +
  3448. +#define DIR_600_A1_GPIO_LED_WPS 0
  3449. +#define DIR_600_A1_GPIO_LED_POWER_AMBER 1
  3450. +#define DIR_600_A1_GPIO_LED_POWER_GREEN 6
  3451. +
  3452. +#define DIR_600_A1_GPIO_BTN_RESET 8
  3453. +#define DIR_600_A1_GPIO_BTN_WPS 12
  3454. +
  3455. +#define DIR_600_A1_BUTTONS_POLL_INTERVAL 20
  3456. +
  3457. +#define DIR_600_A1_NVRAM_ADDR 0x1f030000
  3458. +#define DIR_600_A1_NVRAM_SIZE 0x10000
  3459. +
  3460. +#ifdef CONFIG_MTD_PARTITIONS
  3461. +static struct mtd_partition dir_600_a1_partitions[] = {
  3462. + {
  3463. + .name = "u-boot",
  3464. + .offset = 0,
  3465. + .size = 0x030000,
  3466. + .mask_flags = MTD_WRITEABLE,
  3467. + }, {
  3468. + .name = "nvram",
  3469. + .offset = 0x030000,
  3470. + .size = 0x010000,
  3471. + }, {
  3472. + .name = "kernel",
  3473. + .offset = 0x040000,
  3474. + .size = 0x0e0000,
  3475. + }, {
  3476. + .name = "rootfs",
  3477. + .offset = 0x120000,
  3478. + .size = 0x2c0000,
  3479. + }, {
  3480. + .name = "mac",
  3481. + .offset = 0x3e0000,
  3482. + .size = 0x010000,
  3483. + .mask_flags = MTD_WRITEABLE,
  3484. + }, {
  3485. + .name = "art",
  3486. + .offset = 0x3f0000,
  3487. + .size = 0x010000,
  3488. + .mask_flags = MTD_WRITEABLE,
  3489. + }, {
  3490. + .name = "firmware",
  3491. + .offset = 0x040000,
  3492. + .size = 0x3a0000,
  3493. + }
  3494. +};
  3495. +#endif /* CONFIG_MTD_PARTITIONS */
  3496. +
  3497. +static struct flash_platform_data dir_600_a1_flash_data = {
  3498. +#ifdef CONFIG_MTD_PARTITIONS
  3499. + .parts = dir_600_a1_partitions,
  3500. + .nr_parts = ARRAY_SIZE(dir_600_a1_partitions),
  3501. +#endif
  3502. +};
  3503. +
  3504. +static struct gpio_led dir_600_a1_leds_gpio[] __initdata = {
  3505. + {
  3506. + .name = "dir-600-a1:green:power",
  3507. + .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN,
  3508. + }, {
  3509. + .name = "dir-600-a1:amber:power",
  3510. + .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER,
  3511. + }, {
  3512. + .name = "dir-600-a1:blue:wps",
  3513. + .gpio = DIR_600_A1_GPIO_LED_WPS,
  3514. + .active_low = 1,
  3515. + }
  3516. +};
  3517. +
  3518. +static struct gpio_button dir_600_a1_gpio_buttons[] __initdata = {
  3519. + {
  3520. + .desc = "reset",
  3521. + .type = EV_KEY,
  3522. + .code = KEY_RESTART,
  3523. + .threshold = 3,
  3524. + .gpio = DIR_600_A1_GPIO_BTN_RESET,
  3525. + .active_low = 1,
  3526. + }, {
  3527. + .desc = "wps",
  3528. + .type = EV_KEY,
  3529. + .code = KEY_WPS_BUTTON,
  3530. + .threshold = 3,
  3531. + .gpio = DIR_600_A1_GPIO_BTN_WPS,
  3532. + .active_low = 1,
  3533. + }
  3534. +};
  3535. +
  3536. +static void __init dir_600_a1_setup(void)
  3537. +{
  3538. + const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR);
  3539. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  3540. + u8 mac_buff[6];
  3541. + u8 *mac = NULL;
  3542. +
  3543. + if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE,
  3544. + "lan_mac=", mac_buff) == 0)
  3545. + mac = mac_buff;
  3546. +
  3547. + ar71xx_add_device_m25p80(&dir_600_a1_flash_data);
  3548. +
  3549. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio),
  3550. + dir_600_a1_leds_gpio);
  3551. +
  3552. + ar71xx_add_device_gpio_buttons(-1, DIR_600_A1_BUTTONS_POLL_INTERVAL,
  3553. + ARRAY_SIZE(dir_600_a1_gpio_buttons),
  3554. + dir_600_a1_gpio_buttons);
  3555. +
  3556. + ap91_eth_init(mac, NULL);
  3557. + ap91_pci_init(ee, mac);
  3558. +}
  3559. +
  3560. +MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1",
  3561. + dir_600_a1_setup);
  3562. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.36/arch/mips/ar71xx/mach-dir-615-c1.c
  3563. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100
  3564. +++ linux-2.6.36/arch/mips/ar71xx/mach-dir-615-c1.c 2010-12-17 18:34:51.000000000 +0100
  3565. @@ -0,0 +1,173 @@
  3566. +/*
  3567. + * D-Link DIR-615 rev C1 board support
  3568. + *
  3569. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3570. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3571. + *
  3572. + * This program is free software; you can redistribute it and/or modify it
  3573. + * under the terms of the GNU General Public License version 2 as published
  3574. + * by the Free Software Foundation.
  3575. + */
  3576. +
  3577. +#include <linux/mtd/mtd.h>
  3578. +#include <linux/mtd/partitions.h>
  3579. +
  3580. +#include <asm/mach-ar71xx/ar71xx.h>
  3581. +
  3582. +#include "machtype.h"
  3583. +#include "devices.h"
  3584. +#include "dev-m25p80.h"
  3585. +#include "dev-ar913x-wmac.h"
  3586. +#include "dev-gpio-buttons.h"
  3587. +#include "dev-leds-gpio.h"
  3588. +#include "nvram.h"
  3589. +
  3590. +#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */
  3591. +#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */
  3592. +#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */
  3593. +#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */
  3594. +#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */
  3595. +#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */
  3596. +#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */
  3597. +
  3598. +/* buttons may need refinement */
  3599. +
  3600. +#define DIR_615C1_GPIO_BTN_WPS 12
  3601. +#define DIR_615C1_GPIO_BTN_RESET 21
  3602. +
  3603. +#define DIR_615C1_BUTTONS_POLL_INTERVAL 20
  3604. +
  3605. +#define DIR_615C1_CONFIG_ADDR 0x1f020000
  3606. +#define DIR_615C1_CONFIG_SIZE 0x10000
  3607. +
  3608. +#ifdef CONFIG_MTD_PARTITIONS
  3609. +static struct mtd_partition dir_615c1_partitions[] = {
  3610. + {
  3611. + .name = "u-boot",
  3612. + .offset = 0,
  3613. + .size = 0x020000,
  3614. + .mask_flags = MTD_WRITEABLE,
  3615. + } , {
  3616. + .name = "config",
  3617. + .offset = 0x020000,
  3618. + .size = 0x010000,
  3619. + } , {
  3620. + .name = "kernel",
  3621. + .offset = 0x030000,
  3622. + .size = 0x0d0000,
  3623. + } , {
  3624. + .name = "rootfs",
  3625. + .offset = 0x100000,
  3626. + .size = 0x2f0000,
  3627. + } , {
  3628. + .name = "art",
  3629. + .offset = 0x3f0000,
  3630. + .size = 0x010000,
  3631. + .mask_flags = MTD_WRITEABLE,
  3632. + } , {
  3633. + .name = "firmware",
  3634. + .offset = 0x030000,
  3635. + .size = 0x3c0000,
  3636. + }
  3637. +};
  3638. +#endif /* CONFIG_MTD_PARTITIONS */
  3639. +
  3640. +static struct flash_platform_data dir_615c1_flash_data = {
  3641. +#ifdef CONFIG_MTD_PARTITIONS
  3642. + .parts = dir_615c1_partitions,
  3643. + .nr_parts = ARRAY_SIZE(dir_615c1_partitions),
  3644. +#endif
  3645. +};
  3646. +
  3647. +static struct gpio_led dir_615c1_leds_gpio[] __initdata = {
  3648. + {
  3649. + .name = "dir-615c1:orange:status",
  3650. + .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS,
  3651. + .active_low = 1,
  3652. + }, {
  3653. + .name = "dir-615c1:blue:wps",
  3654. + .gpio = DIR_615C1_GPIO_LED_BLUE_WPS,
  3655. + .active_low = 1,
  3656. + }, {
  3657. + .name = "dir-615c1:green:wan",
  3658. + .gpio = DIR_615C1_GPIO_LED_GREEN_WAN,
  3659. + .active_low = 1,
  3660. + }, {
  3661. + .name = "dir-615c1:green:wancpu",
  3662. + .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU,
  3663. + .active_low = 1,
  3664. + }, {
  3665. + .name = "dir-615c1:green:wlan",
  3666. + .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN,
  3667. + .active_low = 1,
  3668. + }, {
  3669. + .name = "dir-615c1:green:status",
  3670. + .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS,
  3671. + .active_low = 1,
  3672. + }, {
  3673. + .name = "dir-615c1:orange:wan",
  3674. + .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN,
  3675. + .active_low = 1,
  3676. + }
  3677. +
  3678. +};
  3679. +
  3680. +static struct gpio_button dir_615c1_gpio_buttons[] __initdata = {
  3681. + {
  3682. + .desc = "reset",
  3683. + .type = EV_KEY,
  3684. + .code = KEY_RESTART,
  3685. + .threshold = 3,
  3686. + .gpio = DIR_615C1_GPIO_BTN_RESET,
  3687. + }, {
  3688. + .desc = "wps",
  3689. + .type = EV_KEY,
  3690. + .code = KEY_WPS_BUTTON,
  3691. + .threshold = 3,
  3692. + .gpio = DIR_615C1_GPIO_BTN_WPS,
  3693. + }
  3694. +};
  3695. +
  3696. +#define DIR_615C1_LAN_PHYMASK BIT(0)
  3697. +#define DIR_615C1_WAN_PHYMASK BIT(4)
  3698. +#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \
  3699. + DIR_615C1_WAN_PHYMASK))
  3700. +
  3701. +static void __init dir_615c1_setup(void)
  3702. +{
  3703. + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR);
  3704. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3705. + u8 mac[6];
  3706. + u8 *wlan_mac = NULL;
  3707. +
  3708. + if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE,
  3709. + "lan_mac=", mac) == 0) {
  3710. + ar71xx_set_mac_base(mac);
  3711. + wlan_mac = mac;
  3712. + }
  3713. +
  3714. + ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK);
  3715. +
  3716. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3717. + ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK;
  3718. +
  3719. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3720. + ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK;
  3721. +
  3722. + ar71xx_add_device_eth(0);
  3723. + ar71xx_add_device_eth(1);
  3724. +
  3725. + ar71xx_add_device_m25p80(&dir_615c1_flash_data);
  3726. +
  3727. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio),
  3728. + dir_615c1_leds_gpio);
  3729. +
  3730. + ar71xx_add_device_gpio_buttons(-1, DIR_615C1_BUTTONS_POLL_INTERVAL,
  3731. + ARRAY_SIZE(dir_615c1_gpio_buttons),
  3732. + dir_615c1_gpio_buttons);
  3733. +
  3734. + ar913x_add_device_wmac(eeprom, wlan_mac);
  3735. +}
  3736. +
  3737. +MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1",
  3738. + dir_615c1_setup);
  3739. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.36/arch/mips/ar71xx/mach-dir-825-b1.c
  3740. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100
  3741. +++ linux-2.6.36/arch/mips/ar71xx/mach-dir-825-b1.c 2010-12-17 18:34:51.000000000 +0100
  3742. @@ -0,0 +1,192 @@
  3743. +/*
  3744. + * D-Link DIR-825 rev. B1 board support
  3745. + *
  3746. + * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o.
  3747. + *
  3748. + * based on mach-wndr3700.c
  3749. + *
  3750. + * This program is free software; you can redistribute it and/or modify it
  3751. + * under the terms of the GNU General Public License version 2 as published
  3752. + * by the Free Software Foundation.
  3753. + */
  3754. +
  3755. +#include <linux/platform_device.h>
  3756. +#include <linux/mtd/mtd.h>
  3757. +#include <linux/mtd/partitions.h>
  3758. +#include <linux/delay.h>
  3759. +#include <linux/rtl8366s.h>
  3760. +
  3761. +#include <asm/mach-ar71xx/ar71xx.h>
  3762. +
  3763. +#include "machtype.h"
  3764. +#include "devices.h"
  3765. +#include "dev-m25p80.h"
  3766. +#include "dev-ap94-pci.h"
  3767. +#include "dev-gpio-buttons.h"
  3768. +#include "dev-leds-gpio.h"
  3769. +#include "dev-usb.h"
  3770. +
  3771. +#define DIR825B1_GPIO_LED_BLUE_USB 0
  3772. +#define DIR825B1_GPIO_LED_ORANGE_POWER 1
  3773. +#define DIR825B1_GPIO_LED_BLUE_POWER 2
  3774. +#define DIR825B1_GPIO_LED_BLUE_POWERSAVE 4
  3775. +#define DIR825B1_GPIO_LED_ORANGE_PLANET 6
  3776. +#define DIR825B1_GPIO_LED_BLUE_PLANET 11
  3777. +
  3778. +#define DIR825B1_GPIO_BTN_RESET 3
  3779. +#define DIR825B1_GPIO_BTN_POWERSAVE 8
  3780. +
  3781. +#define DIR825B1_GPIO_RTL8366_SDA 5
  3782. +#define DIR825B1_GPIO_RTL8366_SCK 7
  3783. +
  3784. +#define DIR825B1_BUTTONS_POLL_INTERVAL 20
  3785. +
  3786. +#define DIR825B1_CAL_LOCATION_0 0x1f661000
  3787. +#define DIR825B1_CAL_LOCATION_1 0x1f665000
  3788. +
  3789. +#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8
  3790. +#define DIR825B1_MAC_LOCATION_1 0x2ffa8370
  3791. +
  3792. +#ifdef CONFIG_MTD_PARTITIONS
  3793. +static struct mtd_partition dir825b1_partitions[] = {
  3794. + {
  3795. + .name = "uboot",
  3796. + .offset = 0,
  3797. + .size = 0x040000,
  3798. + .mask_flags = MTD_WRITEABLE,
  3799. + } , {
  3800. + .name = "config",
  3801. + .offset = 0x040000,
  3802. + .size = 0x010000,
  3803. + .mask_flags = MTD_WRITEABLE,
  3804. + } , {
  3805. + .name = "firmware",
  3806. + .offset = 0x050000,
  3807. + .size = 0x610000,
  3808. + } , {
  3809. + .name = "caldata",
  3810. + .offset = 0x660000,
  3811. + .size = 0x010000,
  3812. + .mask_flags = MTD_WRITEABLE,
  3813. + } , {
  3814. + .name = "unknown",
  3815. + .offset = 0x670000,
  3816. + .size = 0x190000,
  3817. + .mask_flags = MTD_WRITEABLE,
  3818. + }
  3819. +};
  3820. +#endif /* CONFIG_MTD_PARTITIONS */
  3821. +
  3822. +static struct flash_platform_data dir825b1_flash_data = {
  3823. +#ifdef CONFIG_MTD_PARTITIONS
  3824. + .parts = dir825b1_partitions,
  3825. + .nr_parts = ARRAY_SIZE(dir825b1_partitions),
  3826. +#endif
  3827. +};
  3828. +
  3829. +static struct gpio_led dir825b1_leds_gpio[] __initdata = {
  3830. + {
  3831. + .name = "dir825b1:blue:usb",
  3832. + .gpio = DIR825B1_GPIO_LED_BLUE_USB,
  3833. + .active_low = 1,
  3834. + }, {
  3835. + .name = "dir825b1:orange:power",
  3836. + .gpio = DIR825B1_GPIO_LED_ORANGE_POWER,
  3837. + .active_low = 1,
  3838. + }, {
  3839. + .name = "dir825b1:blue:power",
  3840. + .gpio = DIR825B1_GPIO_LED_BLUE_POWER,
  3841. + .active_low = 1,
  3842. + }, {
  3843. + .name = "dir825b1:blue:powersave",
  3844. + .gpio = DIR825B1_GPIO_LED_BLUE_POWERSAVE,
  3845. + .active_low = 1,
  3846. + }, {
  3847. + .name = "dir825b1:orange:planet",
  3848. + .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET,
  3849. + .active_low = 1,
  3850. + }, {
  3851. + .name = "dir825b1:blue:planet",
  3852. + .gpio = DIR825B1_GPIO_LED_BLUE_PLANET,
  3853. + .active_low = 1,
  3854. + }
  3855. +};
  3856. +
  3857. +static struct gpio_button dir825b1_gpio_buttons[] __initdata = {
  3858. + {
  3859. + .desc = "reset",
  3860. + .type = EV_KEY,
  3861. + .code = KEY_RESTART,
  3862. + .threshold = 3,
  3863. + .gpio = DIR825B1_GPIO_BTN_RESET,
  3864. + .active_low = 1,
  3865. + } , {
  3866. + .desc = "powersave",
  3867. + .type = EV_KEY,
  3868. + .code = BTN_1,
  3869. + .threshold = 3,
  3870. + .gpio = DIR825B1_GPIO_BTN_POWERSAVE,
  3871. + .active_low = 1,
  3872. + }
  3873. +};
  3874. +
  3875. +static struct rtl8366s_platform_data dir825b1_rtl8366s_data = {
  3876. + .gpio_sda = DIR825B1_GPIO_RTL8366_SDA,
  3877. + .gpio_sck = DIR825B1_GPIO_RTL8366_SCK,
  3878. +};
  3879. +
  3880. +static struct platform_device dir825b1_rtl8366s_device = {
  3881. + .name = RTL8366S_DRIVER_NAME,
  3882. + .id = -1,
  3883. + .dev = {
  3884. + .platform_data = &dir825b1_rtl8366s_data,
  3885. + }
  3886. +};
  3887. +
  3888. +static void __init dir825b1_setup(void)
  3889. +{
  3890. + u8 mac[6], i;
  3891. +
  3892. + memcpy(mac, (u8*)KSEG1ADDR(DIR825B1_MAC_LOCATION_1), 6);
  3893. + for(i = 5; i >= 3; i--)
  3894. + if(++mac[i] != 0x00) break;
  3895. +
  3896. + ar71xx_set_mac_base(mac);
  3897. +
  3898. + ar71xx_add_device_mdio(0x0);
  3899. +
  3900. + ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3901. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3902. + ar71xx_eth0_data.speed = SPEED_1000;
  3903. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3904. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  3905. +
  3906. + ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3907. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3908. + ar71xx_eth1_data.phy_mask = 0x10;
  3909. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  3910. +
  3911. + ar71xx_add_device_eth(0);
  3912. + ar71xx_add_device_eth(1);
  3913. +
  3914. + ar71xx_add_device_m25p80(&dir825b1_flash_data);
  3915. +
  3916. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio),
  3917. + dir825b1_leds_gpio);
  3918. +
  3919. + ar71xx_add_device_gpio_buttons(-1, DIR825B1_BUTTONS_POLL_INTERVAL,
  3920. + ARRAY_SIZE(dir825b1_gpio_buttons),
  3921. + dir825b1_gpio_buttons);
  3922. +
  3923. + ar71xx_add_device_usb();
  3924. +
  3925. + platform_device_register(&dir825b1_rtl8366s_device);
  3926. +
  3927. + ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0),
  3928. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0),
  3929. + (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1),
  3930. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1));
  3931. +}
  3932. +
  3933. +MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1",
  3934. + dir825b1_setup);
  3935. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.36/arch/mips/ar71xx/mach-mzk-w04nu.c
  3936. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100
  3937. +++ linux-2.6.36/arch/mips/ar71xx/mach-mzk-w04nu.c 2010-12-17 18:34:51.000000000 +0100
  3938. @@ -0,0 +1,165 @@
  3939. +/*
  3940. + * Planex MZK-W04NU board support
  3941. + *
  3942. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  3943. + *
  3944. + * This program is free software; you can redistribute it and/or modify it
  3945. + * under the terms of the GNU General Public License version 2 as published
  3946. + * by the Free Software Foundation.
  3947. + */
  3948. +
  3949. +#include <linux/mtd/mtd.h>
  3950. +#include <linux/mtd/partitions.h>
  3951. +
  3952. +#include <asm/mach-ar71xx/ar71xx.h>
  3953. +
  3954. +#include "machtype.h"
  3955. +#include "devices.h"
  3956. +#include "dev-ar913x-wmac.h"
  3957. +#include "dev-gpio-buttons.h"
  3958. +#include "dev-leds-gpio.h"
  3959. +#include "dev-m25p80.h"
  3960. +#include "dev-usb.h"
  3961. +
  3962. +#define MZK_W04NU_GPIO_LED_USB 0
  3963. +#define MZK_W04NU_GPIO_LED_STATUS 1
  3964. +#define MZK_W04NU_GPIO_LED_WPS 3
  3965. +#define MZK_W04NU_GPIO_LED_WLAN 6
  3966. +#define MZK_W04NU_GPIO_LED_AP 15
  3967. +#define MZK_W04NU_GPIO_LED_ROUTER 16
  3968. +
  3969. +#define MZK_W04NU_GPIO_BTN_APROUTER 5
  3970. +#define MZK_W04NU_GPIO_BTN_WPS 12
  3971. +#define MZK_W04NU_GPIO_BTN_RESET 21
  3972. +
  3973. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  3974. +
  3975. +#ifdef CONFIG_MTD_PARTITIONS
  3976. +static struct mtd_partition mzk_w04nu_partitions[] = {
  3977. + {
  3978. + .name = "u-boot",
  3979. + .offset = 0,
  3980. + .size = 0x040000,
  3981. + .mask_flags = MTD_WRITEABLE,
  3982. + } , {
  3983. + .name = "u-boot-env",
  3984. + .offset = 0x040000,
  3985. + .size = 0x010000,
  3986. + } , {
  3987. + .name = "kernel",
  3988. + .offset = 0x050000,
  3989. + .size = 0x160000,
  3990. + } , {
  3991. + .name = "rootfs",
  3992. + .offset = 0x1b0000,
  3993. + .size = 0x630000,
  3994. + } , {
  3995. + .name = "art",
  3996. + .offset = 0x7e0000,
  3997. + .size = 0x020000,
  3998. + .mask_flags = MTD_WRITEABLE,
  3999. + } , {
  4000. + .name = "firmware",
  4001. + .offset = 0x050000,
  4002. + .size = 0x790000,
  4003. + }
  4004. +};
  4005. +#endif /* CONFIG_MTD_PARTITIONS */
  4006. +
  4007. +static struct flash_platform_data mzk_w04nu_flash_data = {
  4008. +#ifdef CONFIG_MTD_PARTITIONS
  4009. + .parts = mzk_w04nu_partitions,
  4010. + .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions),
  4011. +#endif
  4012. +};
  4013. +
  4014. +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
  4015. + {
  4016. + .name = "mzk-w04nu:green:status",
  4017. + .gpio = MZK_W04NU_GPIO_LED_STATUS,
  4018. + .active_low = 1,
  4019. + }, {
  4020. + .name = "mzk-w04nu:blue:wps",
  4021. + .gpio = MZK_W04NU_GPIO_LED_WPS,
  4022. + .active_low = 1,
  4023. + }, {
  4024. + .name = "mzk-w04nu:green:wlan",
  4025. + .gpio = MZK_W04NU_GPIO_LED_WLAN,
  4026. + .active_low = 1,
  4027. + }, {
  4028. + .name = "mzk-w04nu:green:usb",
  4029. + .gpio = MZK_W04NU_GPIO_LED_USB,
  4030. + .active_low = 1,
  4031. + }, {
  4032. + .name = "mzk-w04nu:green:ap",
  4033. + .gpio = MZK_W04NU_GPIO_LED_AP,
  4034. + .active_low = 1,
  4035. + }, {
  4036. + .name = "mzk-w04nu:green:router",
  4037. + .gpio = MZK_W04NU_GPIO_LED_ROUTER,
  4038. + .active_low = 1,
  4039. + }
  4040. +};
  4041. +
  4042. +static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = {
  4043. + {
  4044. + .desc = "reset",
  4045. + .type = EV_KEY,
  4046. + .code = KEY_RESTART,
  4047. + .threshold = 3,
  4048. + .gpio = MZK_W04NU_GPIO_BTN_RESET,
  4049. + .active_low = 1,
  4050. + }, {
  4051. + .desc = "wps",
  4052. + .type = EV_KEY,
  4053. + .code = KEY_WPS_BUTTON,
  4054. + .threshold = 3,
  4055. + .gpio = MZK_W04NU_GPIO_BTN_WPS,
  4056. + .active_low = 1,
  4057. + }, {
  4058. + .desc = "aprouter",
  4059. + .type = EV_KEY,
  4060. + .code = BTN_2,
  4061. + .threshold = 3,
  4062. + .gpio = MZK_W04NU_GPIO_BTN_APROUTER,
  4063. + .active_low = 0,
  4064. + }
  4065. +};
  4066. +
  4067. +#define MZK_W04NU_WAN_PHYMASK BIT(4)
  4068. +#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK)
  4069. +
  4070. +static void __init mzk_w04nu_setup(void)
  4071. +{
  4072. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4073. +
  4074. + ar71xx_set_mac_base(eeprom);
  4075. +
  4076. + ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK);
  4077. +
  4078. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4079. + ar71xx_eth0_data.speed = SPEED_100;
  4080. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4081. + ar71xx_eth0_data.has_ar8216 = 1;
  4082. +
  4083. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4084. + ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK;
  4085. +
  4086. + ar71xx_add_device_eth(0);
  4087. + ar71xx_add_device_eth(1);
  4088. +
  4089. + ar71xx_add_device_m25p80(&mzk_w04nu_flash_data);
  4090. +
  4091. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
  4092. + mzk_w04nu_leds_gpio);
  4093. +
  4094. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4095. + ARRAY_SIZE(mzk_w04nu_gpio_buttons),
  4096. + mzk_w04nu_gpio_buttons);
  4097. + ar71xx_add_device_usb();
  4098. +
  4099. + ar913x_add_device_wmac(eeprom, NULL);
  4100. +}
  4101. +
  4102. +MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU",
  4103. + mzk_w04nu_setup);
  4104. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.36/arch/mips/ar71xx/mach-mzk-w300nh.c
  4105. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100
  4106. +++ linux-2.6.36/arch/mips/ar71xx/mach-mzk-w300nh.c 2010-12-17 18:34:51.000000000 +0100
  4107. @@ -0,0 +1,158 @@
  4108. +/*
  4109. + * Planex MZK-W300NH board support
  4110. + *
  4111. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4112. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4113. + *
  4114. + * This program is free software; you can redistribute it and/or modify it
  4115. + * under the terms of the GNU General Public License version 2 as published
  4116. + * by the Free Software Foundation.
  4117. + */
  4118. +
  4119. +#include <linux/mtd/mtd.h>
  4120. +#include <linux/mtd/partitions.h>
  4121. +
  4122. +#include <asm/mach-ar71xx/ar71xx.h>
  4123. +
  4124. +#include "machtype.h"
  4125. +#include "devices.h"
  4126. +#include "dev-m25p80.h"
  4127. +#include "dev-ar913x-wmac.h"
  4128. +#include "dev-gpio-buttons.h"
  4129. +#include "dev-leds-gpio.h"
  4130. +
  4131. +#define MZK_W300NH_GPIO_LED_STATUS 1
  4132. +#define MZK_W300NH_GPIO_LED_WPS 3
  4133. +#define MZK_W300NH_GPIO_LED_WLAN 6
  4134. +#define MZK_W300NH_GPIO_LED_AP 15
  4135. +#define MZK_W300NH_GPIO_LED_ROUTER 16
  4136. +
  4137. +#define MZK_W300NH_GPIO_BTN_APROUTER 5
  4138. +#define MZK_W300NH_GPIO_BTN_WPS 12
  4139. +#define MZK_W300NH_GPIO_BTN_RESET 21
  4140. +
  4141. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  4142. +
  4143. +#ifdef CONFIG_MTD_PARTITIONS
  4144. +static struct mtd_partition mzk_w300nh_partitions[] = {
  4145. + {
  4146. + .name = "u-boot",
  4147. + .offset = 0,
  4148. + .size = 0x040000,
  4149. + .mask_flags = MTD_WRITEABLE,
  4150. + } , {
  4151. + .name = "u-boot-env",
  4152. + .offset = 0x040000,
  4153. + .size = 0x010000,
  4154. + } , {
  4155. + .name = "kernel",
  4156. + .offset = 0x050000,
  4157. + .size = 0x160000,
  4158. + } , {
  4159. + .name = "rootfs",
  4160. + .offset = 0x1b0000,
  4161. + .size = 0x630000,
  4162. + } , {
  4163. + .name = "art",
  4164. + .offset = 0x7e0000,
  4165. + .size = 0x020000,
  4166. + .mask_flags = MTD_WRITEABLE,
  4167. + } , {
  4168. + .name = "firmware",
  4169. + .offset = 0x050000,
  4170. + .size = 0x790000,
  4171. + }
  4172. +};
  4173. +#endif /* CONFIG_MTD_PARTITIONS */
  4174. +
  4175. +static struct flash_platform_data mzk_w300nh_flash_data = {
  4176. +#ifdef CONFIG_MTD_PARTITIONS
  4177. + .parts = mzk_w300nh_partitions,
  4178. + .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions),
  4179. +#endif
  4180. +};
  4181. +
  4182. +static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = {
  4183. + {
  4184. + .name = "mzk-w300nh:green:status",
  4185. + .gpio = MZK_W300NH_GPIO_LED_STATUS,
  4186. + .active_low = 1,
  4187. + }, {
  4188. + .name = "mzk-w300nh:blue:wps",
  4189. + .gpio = MZK_W300NH_GPIO_LED_WPS,
  4190. + .active_low = 1,
  4191. + }, {
  4192. + .name = "mzk-w300nh:green:wlan",
  4193. + .gpio = MZK_W300NH_GPIO_LED_WLAN,
  4194. + .active_low = 1,
  4195. + }, {
  4196. + .name = "mzk-w300nh:green:ap",
  4197. + .gpio = MZK_W300NH_GPIO_LED_AP,
  4198. + .active_low = 1,
  4199. + }, {
  4200. + .name = "mzk-w300nh:green:router",
  4201. + .gpio = MZK_W300NH_GPIO_LED_ROUTER,
  4202. + .active_low = 1,
  4203. + }
  4204. +};
  4205. +
  4206. +static struct gpio_button mzk_w300nh_gpio_buttons[] __initdata = {
  4207. + {
  4208. + .desc = "reset",
  4209. + .type = EV_KEY,
  4210. + .code = KEY_RESTART,
  4211. + .threshold = 3,
  4212. + .gpio = MZK_W300NH_GPIO_BTN_RESET,
  4213. + .active_low = 1,
  4214. + }, {
  4215. + .desc = "wps",
  4216. + .type = EV_KEY,
  4217. + .code = KEY_WPS_BUTTON,
  4218. + .threshold = 3,
  4219. + .gpio = MZK_W300NH_GPIO_BTN_WPS,
  4220. + .active_low = 1,
  4221. + }, {
  4222. + .desc = "aprouter",
  4223. + .type = EV_KEY,
  4224. + .code = BTN_2,
  4225. + .threshold = 3,
  4226. + .gpio = MZK_W300NH_GPIO_BTN_APROUTER,
  4227. + .active_low = 0,
  4228. + }
  4229. +};
  4230. +
  4231. +#define MZK_W300NH_WAN_PHYMASK BIT(4)
  4232. +#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK)
  4233. +
  4234. +static void __init mzk_w300nh_setup(void)
  4235. +{
  4236. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4237. +
  4238. + ar71xx_set_mac_base(eeprom);
  4239. +
  4240. + ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK);
  4241. +
  4242. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4243. + ar71xx_eth0_data.speed = SPEED_100;
  4244. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4245. + ar71xx_eth0_data.has_ar8216 = 1;
  4246. +
  4247. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4248. + ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK;
  4249. +
  4250. + ar71xx_add_device_eth(0);
  4251. + ar71xx_add_device_eth(1);
  4252. +
  4253. + ar71xx_add_device_m25p80(&mzk_w300nh_flash_data);
  4254. +
  4255. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio),
  4256. + mzk_w300nh_leds_gpio);
  4257. +
  4258. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4259. + ARRAY_SIZE(mzk_w300nh_gpio_buttons),
  4260. + mzk_w300nh_gpio_buttons);
  4261. + ar913x_add_device_wmac(eeprom, NULL);
  4262. +}
  4263. +
  4264. +MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH",
  4265. + mzk_w300nh_setup);
  4266. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.36/arch/mips/ar71xx/mach-nbg460n.c
  4267. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100
  4268. +++ linux-2.6.36/arch/mips/ar71xx/mach-nbg460n.c 2010-12-17 18:34:51.000000000 +0100
  4269. @@ -0,0 +1,222 @@
  4270. +/*
  4271. + * Zyxel NBG 460N/550N/550NH board support
  4272. + *
  4273. + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
  4274. + *
  4275. + * based on mach-tl-wr1043nd.c
  4276. + *
  4277. + * This program is free software; you can redistribute it and/or modify it
  4278. + * under the terms of the GNU General Public License version 2 as published
  4279. + * by the Free Software Foundation.
  4280. + */
  4281. +
  4282. +#include <linux/platform_device.h>
  4283. +#include <linux/mtd/mtd.h>
  4284. +#include <linux/mtd/partitions.h>
  4285. +#include <linux/delay.h>
  4286. +#include <linux/rtl8366s.h>
  4287. +
  4288. +#include <linux/i2c.h>
  4289. +#include <linux/i2c-algo-bit.h>
  4290. +#include <linux/i2c-gpio.h>
  4291. +
  4292. +#include <asm/mach-ar71xx/ar71xx.h>
  4293. +
  4294. +#include "machtype.h"
  4295. +#include "devices.h"
  4296. +#include "dev-m25p80.h"
  4297. +#include "dev-ar913x-wmac.h"
  4298. +#include "dev-gpio-buttons.h"
  4299. +#include "dev-leds-gpio.h"
  4300. +
  4301. +/* LEDs */
  4302. +#define NBG460N_GPIO_LED_WPS 3
  4303. +#define NBG460N_GPIO_LED_WAN 6
  4304. +#define NBG460N_GPIO_LED_POWER 14
  4305. +#define NBG460N_GPIO_LED_WLAN 15
  4306. +
  4307. +/* Buttons */
  4308. +#define NBG460N_GPIO_BTN_WPS 12
  4309. +#define NBG460N_GPIO_BTN_RESET 21
  4310. +#define NBG460N_BUTTONS_POLL_INTERVAL 20
  4311. +
  4312. +/* RTC chip PCF8563 I2C interface */
  4313. +#define NBG460N_GPIO_PCF8563_SDA 8
  4314. +#define NBG460N_GPIO_PCF8563_SCK 7
  4315. +
  4316. +/* Switch configuration I2C interface */
  4317. +#define NBG460N_GPIO_RTL8366_SDA 16
  4318. +#define NBG460N_GPIO_RTL8366_SCK 18
  4319. +
  4320. +#ifdef CONFIG_MTD_PARTITIONS
  4321. +static struct mtd_partition nbg460n_partitions[] = {
  4322. + {
  4323. + .name = "Bootbase",
  4324. + .offset = 0,
  4325. + .size = 0x010000,
  4326. + .mask_flags = MTD_WRITEABLE,
  4327. + } , {
  4328. + .name = "U-Boot Config",
  4329. + .offset = 0x010000,
  4330. + .size = 0x030000,
  4331. + } , {
  4332. + .name = "U-Boot",
  4333. + .offset = 0x040000,
  4334. + .size = 0x030000,
  4335. + } , {
  4336. + .name = "linux",
  4337. + .offset = 0x070000,
  4338. + .size = 0x0e0000,
  4339. + } , {
  4340. + .name = "rootfs",
  4341. + .offset = 0x150000,
  4342. + .size = 0x2a0000,
  4343. + } , {
  4344. + .name = "CalibData",
  4345. + .offset = 0x3f0000,
  4346. + .size = 0x010000,
  4347. + .mask_flags = MTD_WRITEABLE,
  4348. + } , {
  4349. + .name = "firmware",
  4350. + .offset = 0x070000,
  4351. + .size = 0x380000,
  4352. + }
  4353. +};
  4354. +#endif /* CONFIG_MTD_PARTITIONS */
  4355. +
  4356. +static struct flash_platform_data nbg460n_flash_data = {
  4357. +#ifdef CONFIG_MTD_PARTITIONS
  4358. + .parts = nbg460n_partitions,
  4359. + .nr_parts = ARRAY_SIZE(nbg460n_partitions),
  4360. +#endif
  4361. +};
  4362. +
  4363. +static struct gpio_led nbg460n_leds_gpio[] __initdata = {
  4364. + {
  4365. + .name = "nbg460n:green:power",
  4366. + .gpio = NBG460N_GPIO_LED_POWER,
  4367. + .active_low = 0,
  4368. + .default_trigger = "default-on",
  4369. + }, {
  4370. + .name = "nbg460n:green:wps",
  4371. + .gpio = NBG460N_GPIO_LED_WPS,
  4372. + .active_low = 0,
  4373. + }, {
  4374. + .name = "nbg460n:green:wlan",
  4375. + .gpio = NBG460N_GPIO_LED_WLAN,
  4376. + .active_low = 0,
  4377. + }, {
  4378. + /* Not really for controlling the LED,
  4379. + when set low the LED blinks uncontrollable */
  4380. + .name = "nbg460n:green:wan",
  4381. + .gpio = NBG460N_GPIO_LED_WAN,
  4382. + .active_low = 0,
  4383. + }
  4384. +};
  4385. +
  4386. +static struct gpio_button nbg460n_gpio_buttons[] __initdata = {
  4387. + {
  4388. + .desc = "reset",
  4389. + .type = EV_KEY,
  4390. + .code = KEY_RESTART,
  4391. + .threshold = 3,
  4392. + .gpio = NBG460N_GPIO_BTN_RESET,
  4393. + .active_low = 1,
  4394. + }, {
  4395. + .desc = "wps",
  4396. + .type = EV_KEY,
  4397. + .code = KEY_WPS_BUTTON,
  4398. + .threshold = 3,
  4399. + .gpio = NBG460N_GPIO_BTN_WPS,
  4400. + .active_low = 1,
  4401. + }
  4402. +};
  4403. +
  4404. +static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = {
  4405. + .sda_pin = NBG460N_GPIO_PCF8563_SDA,
  4406. + .scl_pin = NBG460N_GPIO_PCF8563_SCK,
  4407. + .udelay = 10,
  4408. +};
  4409. +
  4410. +static struct platform_device nbg460n_i2c_device = {
  4411. + .name = "i2c-gpio",
  4412. + .id = -1,
  4413. + .num_resources = 0,
  4414. + .resource = NULL,
  4415. + .dev = {
  4416. + .platform_data = &nbg460n_i2c_device_platdata,
  4417. + },
  4418. +};
  4419. +
  4420. +static struct i2c_board_info nbg460n_i2c_devs[] __initdata = {
  4421. + {
  4422. + I2C_BOARD_INFO("pcf8563", 0x51),
  4423. + },
  4424. +};
  4425. +
  4426. +static void __devinit nbg460n_i2c_init(void)
  4427. +{
  4428. + /* The gpio interface */
  4429. + platform_device_register(&nbg460n_i2c_device);
  4430. + /* I2C devices */
  4431. + i2c_register_board_info(0, nbg460n_i2c_devs,
  4432. + ARRAY_SIZE(nbg460n_i2c_devs));
  4433. +}
  4434. +
  4435. +
  4436. +static struct rtl8366s_platform_data nbg460n_rtl8366s_data = {
  4437. + .gpio_sda = NBG460N_GPIO_RTL8366_SDA,
  4438. + .gpio_sck = NBG460N_GPIO_RTL8366_SCK,
  4439. +};
  4440. +
  4441. +static struct platform_device nbg460n_rtl8366s_device = {
  4442. + .name = RTL8366S_DRIVER_NAME,
  4443. + .id = -1,
  4444. + .dev = {
  4445. + .platform_data = &nbg460n_rtl8366s_data,
  4446. + }
  4447. +};
  4448. +
  4449. +static void __init nbg460n_setup(void)
  4450. +{
  4451. + /* end of bootloader sector contains mac address*/
  4452. + u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8);
  4453. + /* last sector contains wlan calib data */
  4454. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4455. +
  4456. + ar71xx_set_mac_base(mac);
  4457. +
  4458. + /* LAN Port */
  4459. + ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4460. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4461. + ar71xx_eth0_data.speed = SPEED_1000;
  4462. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4463. +
  4464. + /* WAN Port */
  4465. + ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4466. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4467. + ar71xx_eth1_data.phy_mask = 0x10;
  4468. +
  4469. + ar71xx_add_device_eth(0);
  4470. + ar71xx_add_device_eth(1);
  4471. +
  4472. + /* register the switch phy */
  4473. + platform_device_register(&nbg460n_rtl8366s_device);
  4474. +
  4475. + /* register flash */
  4476. + ar71xx_add_device_m25p80(&nbg460n_flash_data);
  4477. +
  4478. + ar913x_add_device_wmac(eeprom, mac);
  4479. +
  4480. + /* register RTC chip */
  4481. + nbg460n_i2c_init();
  4482. +
  4483. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio),
  4484. + nbg460n_leds_gpio);
  4485. +
  4486. + ar71xx_add_device_gpio_buttons(-1, NBG460N_BUTTONS_POLL_INTERVAL,
  4487. + ARRAY_SIZE(nbg460n_gpio_buttons),
  4488. + nbg460n_gpio_buttons);
  4489. +}
  4490. +
  4491. +MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", nbg460n_setup);
  4492. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.36/arch/mips/ar71xx/mach-pb42.c
  4493. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100
  4494. +++ linux-2.6.36/arch/mips/ar71xx/mach-pb42.c 2010-12-17 18:34:51.000000000 +0100
  4495. @@ -0,0 +1,71 @@
  4496. +/*
  4497. + * Atheros PB42 board support
  4498. + *
  4499. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4500. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4501. + *
  4502. + * This program is free software; you can redistribute it and/or modify it
  4503. + * under the terms of the GNU General Public License version 2 as published
  4504. + * by the Free Software Foundation.
  4505. + */
  4506. +
  4507. +#include <asm/mach-ar71xx/ar71xx.h>
  4508. +
  4509. +#include "machtype.h"
  4510. +#include "devices.h"
  4511. +#include "dev-m25p80.h"
  4512. +#include "dev-gpio-buttons.h"
  4513. +#include "dev-pb42-pci.h"
  4514. +#include "dev-usb.h"
  4515. +
  4516. +#define PB42_BUTTONS_POLL_INTERVAL 20
  4517. +
  4518. +#define PB42_GPIO_BTN_SW4 8
  4519. +#define PB42_GPIO_BTN_SW5 3
  4520. +
  4521. +static struct gpio_button pb42_gpio_buttons[] __initdata = {
  4522. + {
  4523. + .desc = "sw4",
  4524. + .type = EV_KEY,
  4525. + .code = BTN_0,
  4526. + .threshold = 3,
  4527. + .gpio = PB42_GPIO_BTN_SW4,
  4528. + .active_low = 1,
  4529. + } , {
  4530. + .desc = "sw5",
  4531. + .type = EV_KEY,
  4532. + .code = BTN_1,
  4533. + .threshold = 3,
  4534. + .gpio = PB42_GPIO_BTN_SW5,
  4535. + .active_low = 1,
  4536. + }
  4537. +};
  4538. +
  4539. +#define PB42_WAN_PHYMASK BIT(20)
  4540. +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  4541. +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
  4542. +
  4543. +static void __init pb42_init(void)
  4544. +{
  4545. + ar71xx_add_device_m25p80(NULL);
  4546. +
  4547. + ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
  4548. +
  4549. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  4550. + ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
  4551. +
  4552. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4553. + ar71xx_eth1_data.speed = SPEED_100;
  4554. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4555. +
  4556. + ar71xx_add_device_eth(0);
  4557. + ar71xx_add_device_eth(1);
  4558. +
  4559. + ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL,
  4560. + ARRAY_SIZE(pb42_gpio_buttons),
  4561. + pb42_gpio_buttons);
  4562. +
  4563. + pb42_pci_init();
  4564. +}
  4565. +
  4566. +MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init);
  4567. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.36/arch/mips/ar71xx/mach-pb44.c
  4568. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100
  4569. +++ linux-2.6.36/arch/mips/ar71xx/mach-pb44.c 2010-12-17 18:34:51.000000000 +0100
  4570. @@ -0,0 +1,207 @@
  4571. +/*
  4572. + * Atheros PB44 board support
  4573. + *
  4574. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  4575. + *
  4576. + * This program is free software; you can redistribute it and/or modify it
  4577. + * under the terms of the GNU General Public License version 2 as published
  4578. + * by the Free Software Foundation.
  4579. + */
  4580. +
  4581. +#include <linux/init.h>
  4582. +#include <linux/bitops.h>
  4583. +#include <linux/delay.h>
  4584. +#include <linux/platform_device.h>
  4585. +#include <linux/spi/spi.h>
  4586. +#include <linux/spi/flash.h>
  4587. +#include <linux/spi/vsc7385.h>
  4588. +#include <linux/i2c.h>
  4589. +#include <linux/i2c-gpio.h>
  4590. +#include <linux/i2c/pcf857x.h>
  4591. +
  4592. +#include <asm/mach-ar71xx/ar71xx.h>
  4593. +
  4594. +#include "machtype.h"
  4595. +#include "devices.h"
  4596. +#include "dev-pb42-pci.h"
  4597. +#include "dev-gpio-buttons.h"
  4598. +#include "dev-leds-gpio.h"
  4599. +#include "dev-usb.h"
  4600. +
  4601. +#define PB44_PCF8757_VSC7395_CS 0
  4602. +#define PB44_PCF8757_STEREO_CS 1
  4603. +#define PB44_PCF8757_SLIC_CS0 2
  4604. +#define PB44_PCF8757_SLIC_TEST 3
  4605. +#define PB44_PCF8757_SLIC_INT0 4
  4606. +#define PB44_PCF8757_SLIC_INT1 5
  4607. +#define PB44_PCF8757_SW_RESET 6
  4608. +#define PB44_PCF8757_SW_JUMP 8
  4609. +#define PB44_PCF8757_LED_JUMP1 9
  4610. +#define PB44_PCF8757_LED_JUMP2 10
  4611. +#define PB44_PCF8757_TP24 11
  4612. +#define PB44_PCF8757_TP25 12
  4613. +#define PB44_PCF8757_TP26 13
  4614. +#define PB44_PCF8757_TP27 14
  4615. +#define PB44_PCF8757_TP28 15
  4616. +
  4617. +#define PB44_GPIO_I2C_SCL 0
  4618. +#define PB44_GPIO_I2C_SDA 1
  4619. +
  4620. +#define PB44_GPIO_EXP_BASE 16
  4621. +#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS)
  4622. +#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET)
  4623. +#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP)
  4624. +#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1)
  4625. +#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2)
  4626. +
  4627. +static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
  4628. + .sda_pin = PB44_GPIO_I2C_SDA,
  4629. + .scl_pin = PB44_GPIO_I2C_SCL,
  4630. +};
  4631. +
  4632. +static struct platform_device pb44_i2c_gpio_device = {
  4633. + .name = "i2c-gpio",
  4634. + .id = 0,
  4635. + .dev = {
  4636. + .platform_data = &pb44_i2c_gpio_data,
  4637. + }
  4638. +};
  4639. +
  4640. +static struct pcf857x_platform_data pb44_pcf857x_data = {
  4641. + .gpio_base = PB44_GPIO_EXP_BASE,
  4642. +};
  4643. +
  4644. +static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
  4645. + {
  4646. + I2C_BOARD_INFO("pcf8575", 0x20),
  4647. + .platform_data = &pb44_pcf857x_data,
  4648. + },
  4649. +};
  4650. +
  4651. +static struct gpio_led pb44_leds_gpio[] __initdata = {
  4652. + {
  4653. + .name = "pb44:amber:jump1",
  4654. + .gpio = PB44_GPIO_LED_JUMP1,
  4655. + .active_low = 1,
  4656. + }, {
  4657. + .name = "pb44:green:jump2",
  4658. + .gpio = PB44_GPIO_LED_JUMP2,
  4659. + .active_low = 1,
  4660. + },
  4661. +};
  4662. +
  4663. +static struct gpio_button pb44_gpio_buttons[] __initdata = {
  4664. + {
  4665. + .desc = "soft_reset",
  4666. + .type = EV_KEY,
  4667. + .code = KEY_RESTART,
  4668. + .threshold = 3,
  4669. + .gpio = PB44_GPIO_SW_RESET,
  4670. + .active_low = 1,
  4671. + } , {
  4672. + .desc = "jumpstart",
  4673. + .type = EV_KEY,
  4674. + .code = KEY_WPS_BUTTON,
  4675. + .threshold = 3,
  4676. + .gpio = PB44_GPIO_SW_JUMP,
  4677. + .active_low = 1,
  4678. + }
  4679. +};
  4680. +
  4681. +static void pb44_vsc7395_reset(void)
  4682. +{
  4683. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  4684. + udelay(10);
  4685. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  4686. + mdelay(50);
  4687. +}
  4688. +
  4689. +static struct vsc7385_platform_data pb44_vsc7395_data = {
  4690. + .reset = pb44_vsc7395_reset,
  4691. + .ucode_name = "vsc7395_ucode_pb44.bin",
  4692. + .mac_cfg = {
  4693. + .tx_ipg = 6,
  4694. + .bit2 = 1,
  4695. + .clk_sel = 0,
  4696. + },
  4697. +};
  4698. +
  4699. +static struct spi_board_info pb44_spi_info[] = {
  4700. + {
  4701. + .bus_num = 0,
  4702. + .chip_select = 0,
  4703. + .max_speed_hz = 25000000,
  4704. + .modalias = "m25p80",
  4705. + }, {
  4706. + .bus_num = 0,
  4707. + .chip_select = 1,
  4708. + .max_speed_hz = 25000000,
  4709. + .modalias = "spi-vsc7385",
  4710. + .platform_data = &pb44_vsc7395_data,
  4711. + .controller_data = (void *) PB44_GPIO_VSC7395_CS,
  4712. + },
  4713. +};
  4714. +
  4715. +static struct resource pb44_spi_resources[] = {
  4716. + [0] = {
  4717. + .start = AR71XX_SPI_BASE,
  4718. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  4719. + .flags = IORESOURCE_MEM,
  4720. + },
  4721. +};
  4722. +
  4723. +static struct ar71xx_spi_platform_data pb44_spi_data = {
  4724. + .bus_num = 0,
  4725. + .num_chipselect = 2,
  4726. +};
  4727. +
  4728. +static struct platform_device pb44_spi_device = {
  4729. + .name = "pb44-spi",
  4730. + .id = -1,
  4731. + .resource = pb44_spi_resources,
  4732. + .num_resources = ARRAY_SIZE(pb44_spi_resources),
  4733. + .dev = {
  4734. + .platform_data = &pb44_spi_data,
  4735. + },
  4736. +};
  4737. +
  4738. +#define PB44_WAN_PHYMASK BIT(0)
  4739. +#define PB44_LAN_PHYMASK 0
  4740. +#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK)
  4741. +
  4742. +static void __init pb44_init(void)
  4743. +{
  4744. + ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK);
  4745. +
  4746. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4747. + ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK;
  4748. +
  4749. + ar71xx_add_device_eth(0);
  4750. +
  4751. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4752. + ar71xx_eth1_data.speed = SPEED_1000;
  4753. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4754. + ar71xx_eth1_pll_data.pll_1000 = 0x110000;
  4755. +
  4756. + ar71xx_add_device_eth(1);
  4757. +
  4758. + ar71xx_add_device_usb();
  4759. +
  4760. + pb42_pci_init();
  4761. +
  4762. + i2c_register_board_info(0, pb44_i2c_board_info,
  4763. + ARRAY_SIZE(pb44_i2c_board_info));
  4764. +
  4765. + platform_device_register(&pb44_i2c_gpio_device);
  4766. +
  4767. + spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info));
  4768. + platform_device_register(&pb44_spi_device);
  4769. +
  4770. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
  4771. + pb44_leds_gpio);
  4772. +
  4773. + ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(pb44_gpio_buttons),
  4774. + pb44_gpio_buttons);
  4775. +}
  4776. +
  4777. +MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init);
  4778. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.36/arch/mips/ar71xx/mach-pb92.c
  4779. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100
  4780. +++ linux-2.6.36/arch/mips/ar71xx/mach-pb92.c 2010-12-17 18:34:51.000000000 +0100
  4781. @@ -0,0 +1,109 @@
  4782. +/*
  4783. + * Atheros PB92 board support
  4784. + *
  4785. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  4786. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4787. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4788. + *
  4789. + * This program is free software; you can redistribute it and/or modify it
  4790. + * under the terms of the GNU General Public License version 2 as published
  4791. + * by the Free Software Foundation.
  4792. + */
  4793. +
  4794. +#include <linux/mtd/mtd.h>
  4795. +#include <linux/mtd/partitions.h>
  4796. +#include <asm/mach-ar71xx/ar71xx.h>
  4797. +
  4798. +#include "machtype.h"
  4799. +#include "devices.h"
  4800. +#include "dev-m25p80.h"
  4801. +#include "dev-gpio-buttons.h"
  4802. +#include "dev-pb9x-pci.h"
  4803. +#include "dev-usb.h"
  4804. +
  4805. +#ifdef CONFIG_MTD_PARTITIONS
  4806. +static struct mtd_partition pb92_partitions[] = {
  4807. + {
  4808. + .name = "u-boot",
  4809. + .offset = 0,
  4810. + .size = 0x040000,
  4811. + .mask_flags = MTD_WRITEABLE,
  4812. + } , {
  4813. + .name = "u-boot-env",
  4814. + .offset = 0x040000,
  4815. + .size = 0x010000,
  4816. + } , {
  4817. + .name = "rootfs",
  4818. + .offset = 0x050000,
  4819. + .size = 0x2b0000,
  4820. + } , {
  4821. + .name = "uImage",
  4822. + .offset = 0x300000,
  4823. + .size = 0x0e0000,
  4824. + } , {
  4825. + .name = "ART",
  4826. + .offset = 0x3e0000,
  4827. + .size = 0x020000,
  4828. + .mask_flags = MTD_WRITEABLE,
  4829. + }
  4830. +};
  4831. +#endif /* CONFIG_MTD_PARTITIONS */
  4832. +
  4833. +static struct flash_platform_data pb92_flash_data = {
  4834. +#ifdef CONFIG_MTD_PARTITIONS
  4835. + .parts = pb92_partitions,
  4836. + .nr_parts = ARRAY_SIZE(pb92_partitions),
  4837. +#endif
  4838. +};
  4839. +
  4840. +
  4841. +#define PB92_BUTTONS_POLL_INTERVAL 20
  4842. +
  4843. +#define PB92_GPIO_BTN_SW4 8
  4844. +#define PB92_GPIO_BTN_SW5 3
  4845. +
  4846. +static struct gpio_button pb92_gpio_buttons[] __initdata = {
  4847. + {
  4848. + .desc = "sw4",
  4849. + .type = EV_KEY,
  4850. + .code = BTN_0,
  4851. + .threshold = 3,
  4852. + .gpio = PB92_GPIO_BTN_SW4,
  4853. + .active_low = 1,
  4854. + } , {
  4855. + .desc = "sw5",
  4856. + .type = EV_KEY,
  4857. + .code = BTN_1,
  4858. + .threshold = 3,
  4859. + .gpio = PB92_GPIO_BTN_SW5,
  4860. + .active_low = 1,
  4861. + }
  4862. +};
  4863. +
  4864. +static void __init pb92_init(void)
  4865. +{
  4866. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  4867. +
  4868. + ar71xx_set_mac_base(mac);
  4869. + ar71xx_add_device_m25p80(&pb92_flash_data);
  4870. +
  4871. + ar71xx_add_device_mdio(~0);
  4872. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4873. + ar71xx_eth0_data.speed = SPEED_1000;
  4874. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4875. +
  4876. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4877. + ar71xx_eth1_data.speed = SPEED_1000;
  4878. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4879. +
  4880. + ar71xx_add_device_eth(0);
  4881. + ar71xx_add_device_eth(1);
  4882. +
  4883. + ar71xx_add_device_gpio_buttons(-1, PB92_BUTTONS_POLL_INTERVAL,
  4884. + ARRAY_SIZE(pb92_gpio_buttons),
  4885. + pb92_gpio_buttons);
  4886. +
  4887. + pb9x_pci_init();
  4888. +}
  4889. +
  4890. +MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init);
  4891. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.36/arch/mips/ar71xx/mach-rb4xx.c
  4892. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100
  4893. +++ linux-2.6.36/arch/mips/ar71xx/mach-rb4xx.c 2010-12-17 18:34:51.000000000 +0100
  4894. @@ -0,0 +1,290 @@
  4895. +/*
  4896. + * MikroTik RouterBOARD 4xx series support
  4897. + *
  4898. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4899. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4900. + *
  4901. + * This program is free software; you can redistribute it and/or modify it
  4902. + * under the terms of the GNU General Public License version 2 as published
  4903. + * by the Free Software Foundation.
  4904. + */
  4905. +
  4906. +#include <linux/platform_device.h>
  4907. +#include <linux/irq.h>
  4908. +#include <linux/mmc/host.h>
  4909. +#include <linux/spi/spi.h>
  4910. +#include <linux/spi/flash.h>
  4911. +#include <linux/spi/mmc_spi.h>
  4912. +
  4913. +#include <asm/mach-ar71xx/ar71xx.h>
  4914. +#include <asm/mach-ar71xx/pci.h>
  4915. +
  4916. +#include "machtype.h"
  4917. +#include "devices.h"
  4918. +#include "dev-gpio-buttons.h"
  4919. +#include "dev-leds-gpio.h"
  4920. +#include "dev-usb.h"
  4921. +
  4922. +#define RB4XX_GPIO_USER_LED 4
  4923. +#define RB4XX_GPIO_RESET_SWITCH 7
  4924. +
  4925. +#define RB4XX_BUTTONS_POLL_INTERVAL 20
  4926. +
  4927. +static struct gpio_led rb4xx_leds_gpio[] __initdata = {
  4928. + {
  4929. + .name = "rb4xx:yellow:user",
  4930. + .gpio = RB4XX_GPIO_USER_LED,
  4931. + .active_low = 0,
  4932. + },
  4933. +};
  4934. +
  4935. +static struct gpio_button rb4xx_gpio_buttons[] __initdata = {
  4936. + {
  4937. + .desc = "reset_switch",
  4938. + .type = EV_KEY,
  4939. + .code = KEY_RESTART,
  4940. + .threshold = 3,
  4941. + .gpio = RB4XX_GPIO_RESET_SWITCH,
  4942. + .active_low = 1,
  4943. + }
  4944. +};
  4945. +
  4946. +static struct platform_device rb4xx_nand_device = {
  4947. + .name = "rb4xx-nand",
  4948. + .id = -1,
  4949. +};
  4950. +
  4951. +static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
  4952. + {
  4953. + .slot = 0,
  4954. + .pin = 1,
  4955. + .irq = AR71XX_PCI_IRQ_DEV2,
  4956. + }, {
  4957. + .slot = 1,
  4958. + .pin = 1,
  4959. + .irq = AR71XX_PCI_IRQ_DEV0,
  4960. + }, {
  4961. + .slot = 1,
  4962. + .pin = 2,
  4963. + .irq = AR71XX_PCI_IRQ_DEV1,
  4964. + }, {
  4965. + .slot = 2,
  4966. + .pin = 1,
  4967. + .irq = AR71XX_PCI_IRQ_DEV1,
  4968. + }, {
  4969. + .slot = 3,
  4970. + .pin = 1,
  4971. + .irq = AR71XX_PCI_IRQ_DEV2,
  4972. + }
  4973. +};
  4974. +
  4975. +#if 0
  4976. +/*
  4977. + * SPI device support is experimental
  4978. + */
  4979. +static struct flash_platform_data rb4xx_flash_data = {
  4980. + .type = "pm25lv512",
  4981. +};
  4982. +
  4983. +static struct spi_board_info rb4xx_spi_info[] = {
  4984. + {
  4985. + .bus_num = 0,
  4986. + .chip_select = 0,
  4987. + .max_speed_hz = 25000000,
  4988. + .modalias = "m25p80",
  4989. + .platform_data = &rb4xx_flash_data,
  4990. + }
  4991. +};
  4992. +
  4993. +static struct mmc_spi_platform_data rb433_mmc_data = {
  4994. + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
  4995. +};
  4996. +
  4997. +static struct spi_board_info rb433_spi_info[] = {
  4998. + {
  4999. + .bus_num = 0,
  5000. + .chip_select = 0,
  5001. + .max_speed_hz = 25000000,
  5002. + .modalias = "m25p80",
  5003. + .platform_data = &rb433_flash_data,
  5004. + }, {
  5005. + .bus_num = 0,
  5006. + .chip_select = 2,
  5007. + .max_speed_hz = 25000000,
  5008. + .modalias = "mmc_spi",
  5009. + .platform_data = &rb433_mmc_data,
  5010. + }
  5011. +};
  5012. +
  5013. +static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  5014. +{
  5015. + u32 ret;
  5016. +
  5017. + if (is_on == AR71XX_SPI_CS_INACTIVE) {
  5018. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5019. + } else {
  5020. + if (cs_high) {
  5021. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5022. + } else {
  5023. + if ((chip_select ^ 2) == 0)
  5024. + ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5025. + else
  5026. + ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5027. + }
  5028. + }
  5029. +
  5030. + return ret;
  5031. +}
  5032. +
  5033. +struct ar71xx_spi_platform_data rb433_spi_data = {
  5034. + .bus_num = 0,
  5035. + .num_chipselect = 3,
  5036. + .get_ioc_base = rb433_spi_get_ioc_base,
  5037. +};
  5038. +
  5039. +static void rb4xx_add_device_spi(void)
  5040. +{
  5041. + ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
  5042. +}
  5043. +
  5044. +static void rb433_add_device_spi(void)
  5045. +{
  5046. + ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info,
  5047. + ARRAY_SIZE(rb433_spi_info));
  5048. +}
  5049. +#else
  5050. +static inline void rb4xx_add_device_spi(void) {}
  5051. +static inline void rb433_add_device_spi(void) {}
  5052. +#endif
  5053. +
  5054. +static void __init rb4xx_generic_setup(void)
  5055. +{
  5056. + ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN |
  5057. + AR71XX_GPIO_FUNC_SPI_CS2_EN);
  5058. +
  5059. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
  5060. + rb4xx_leds_gpio);
  5061. +
  5062. + ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL,
  5063. + ARRAY_SIZE(rb4xx_gpio_buttons),
  5064. + rb4xx_gpio_buttons);
  5065. +
  5066. + platform_device_register(&rb4xx_nand_device);
  5067. +}
  5068. +
  5069. +static void __init rb411_setup(void)
  5070. +{
  5071. + rb4xx_generic_setup();
  5072. + rb4xx_add_device_spi();
  5073. +
  5074. + ar71xx_add_device_mdio(0xfffffffc);
  5075. +
  5076. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5077. + ar71xx_eth0_data.phy_mask = 0x00000003;
  5078. +
  5079. + ar71xx_add_device_eth(0);
  5080. +
  5081. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5082. +}
  5083. +
  5084. +MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH",
  5085. + rb411_setup);
  5086. +
  5087. +static void __init rb411u_setup(void)
  5088. +{
  5089. + rb411_setup();
  5090. + ar71xx_add_device_usb();
  5091. +}
  5092. +
  5093. +MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U",
  5094. + rb411u_setup);
  5095. +
  5096. +static void __init rb433_setup(void)
  5097. +{
  5098. + rb4xx_generic_setup();
  5099. + rb433_add_device_spi();
  5100. +
  5101. + ar71xx_add_device_mdio(0xffffffe9);
  5102. +
  5103. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5104. + ar71xx_eth0_data.speed = SPEED_100;
  5105. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5106. +
  5107. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5108. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5109. +
  5110. + ar71xx_add_device_eth(1);
  5111. + ar71xx_add_device_eth(0);
  5112. +
  5113. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5114. +}
  5115. +
  5116. +MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH",
  5117. + rb433_setup);
  5118. +
  5119. +static void __init rb433u_setup(void)
  5120. +{
  5121. + rb433_setup();
  5122. + ar71xx_add_device_usb();
  5123. +}
  5124. +
  5125. +MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH",
  5126. + rb433u_setup);
  5127. +
  5128. +static void __init rb450_generic_setup(int gige)
  5129. +{
  5130. + rb4xx_generic_setup();
  5131. + rb4xx_add_device_spi();
  5132. +
  5133. + ar71xx_add_device_mdio(0xffffffe0);
  5134. +
  5135. + ar71xx_eth0_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII;
  5136. + ar71xx_eth0_data.phy_mask = (gige) ? (1 << 0) : 0;
  5137. + ar71xx_eth0_data.speed = (gige) ? SPEED_1000 : SPEED_100;
  5138. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5139. +
  5140. + ar71xx_eth1_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII;
  5141. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5142. +
  5143. + ar71xx_add_device_eth(1);
  5144. + ar71xx_add_device_eth(0);
  5145. +}
  5146. +
  5147. +static void __init rb450_setup(void)
  5148. +{
  5149. + rb450_generic_setup(0);
  5150. +}
  5151. +
  5152. +MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450",
  5153. + rb450_setup);
  5154. +
  5155. +static void __init rb450g_setup(void)
  5156. +{
  5157. + rb450_generic_setup(1);
  5158. +}
  5159. +
  5160. +MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G",
  5161. + rb450g_setup);
  5162. +
  5163. +static void __init rb493_setup(void)
  5164. +{
  5165. + rb4xx_generic_setup();
  5166. + rb4xx_add_device_spi();
  5167. +
  5168. + ar71xx_add_device_mdio(0x3fffff00);
  5169. +
  5170. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5171. + ar71xx_eth0_data.speed = SPEED_100;
  5172. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5173. +
  5174. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5175. + ar71xx_eth1_data.phy_mask = 0x00000001;
  5176. +
  5177. + ar71xx_add_device_eth(0);
  5178. + ar71xx_add_device_eth(1);
  5179. +
  5180. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5181. +}
  5182. +
  5183. +MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH",
  5184. + rb493_setup);
  5185. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.36/arch/mips/ar71xx/mach-rb750.c
  5186. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100
  5187. +++ linux-2.6.36/arch/mips/ar71xx/mach-rb750.c 2010-12-17 18:34:51.000000000 +0100
  5188. @@ -0,0 +1,133 @@
  5189. +/*
  5190. + * MikroTik RouterBOARD 750 support
  5191. + *
  5192. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  5193. + *
  5194. + * This program is free software; you can redistribute it and/or modify it
  5195. + * under the terms of the GNU General Public License version 2 as published
  5196. + * by the Free Software Foundation.
  5197. + */
  5198. +
  5199. +#include <linux/platform_device.h>
  5200. +#include <asm/mach-ar71xx/ar71xx.h>
  5201. +#include <asm/mach-ar71xx/mach-rb750.h>
  5202. +
  5203. +#include "machtype.h"
  5204. +#include "dev-ap91-eth.h"
  5205. +
  5206. +static struct rb750_led_data rb750_leds[] = {
  5207. + {
  5208. + .name = "rb750:green:act",
  5209. + .mask = RB750_LED_ACT,
  5210. + .active_low = 1,
  5211. + }, {
  5212. + .name = "rb750:green:port1",
  5213. + .mask = RB750_LED_PORT5,
  5214. + .active_low = 1,
  5215. + }, {
  5216. + .name = "rb750:green:port2",
  5217. + .mask = RB750_LED_PORT4,
  5218. + .active_low = 1,
  5219. + }, {
  5220. + .name = "rb750:green:port3",
  5221. + .mask = RB750_LED_PORT3,
  5222. + .active_low = 1,
  5223. + }, {
  5224. + .name = "rb750:green:port4",
  5225. + .mask = RB750_LED_PORT2,
  5226. + .active_low = 1,
  5227. + }, {
  5228. + .name = "rb750:green:port5",
  5229. + .mask = RB750_LED_PORT1,
  5230. + .active_low = 1,
  5231. + }
  5232. +};
  5233. +
  5234. +static struct rb750_led_platform_data rb750_leds_data = {
  5235. + .num_leds = ARRAY_SIZE(rb750_leds),
  5236. + .leds = rb750_leds,
  5237. +};
  5238. +
  5239. +static struct platform_device rb750_leds_device = {
  5240. + .name = "leds-rb750",
  5241. + .dev = {
  5242. + .platform_data = &rb750_leds_data,
  5243. + }
  5244. +};
  5245. +
  5246. +static const char *rb750_port_names[AP91_ETH_NUM_PORT_NAMES] __initdata = {
  5247. + "port5",
  5248. + "port4",
  5249. + "port3",
  5250. + "port2",
  5251. +};
  5252. +
  5253. +static struct platform_device rb750_nand_device = {
  5254. + .name = "rb750-nand",
  5255. + .id = -1,
  5256. +};
  5257. +
  5258. +int rb750_latch_change(u32 mask_clr, u32 mask_set)
  5259. +{
  5260. + static DEFINE_SPINLOCK(lock);
  5261. + static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE;
  5262. + static u32 latch_oe;
  5263. + static u32 latch_clr;
  5264. + unsigned long flags;
  5265. + u32 t;
  5266. + int ret = 0;
  5267. +
  5268. + spin_lock_irqsave(&lock, flags);
  5269. +
  5270. + if ((mask_clr & BIT(31)) != 0 &&
  5271. + (latch_set & RB750_LVC573_LE) == 0) {
  5272. + goto unlock;
  5273. + }
  5274. +
  5275. + latch_set = (latch_set | mask_set) & ~mask_clr;
  5276. + latch_clr = (latch_clr | mask_clr) & ~mask_set;
  5277. +
  5278. + if (latch_oe == 0)
  5279. + latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE);
  5280. +
  5281. + if (likely(latch_set & RB750_LVC573_LE)) {
  5282. + void __iomem *base = ar71xx_gpio_base;
  5283. +
  5284. + t = __raw_readl(base + GPIO_REG_OE);
  5285. + t |= mask_clr | latch_oe | mask_set;
  5286. +
  5287. + __raw_writel(t, base + GPIO_REG_OE);
  5288. + __raw_writel(latch_clr, base + GPIO_REG_CLEAR);
  5289. + __raw_writel(latch_set, base + GPIO_REG_SET);
  5290. + } else if (mask_clr & RB750_LVC573_LE) {
  5291. + void __iomem *base = ar71xx_gpio_base;
  5292. +
  5293. + latch_oe = __raw_readl(base + GPIO_REG_OE);
  5294. + __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR);
  5295. + /* flush write */
  5296. + __raw_readl(base + GPIO_REG_CLEAR);
  5297. + }
  5298. +
  5299. + ret = 1;
  5300. +
  5301. + unlock:
  5302. + spin_unlock_irqrestore(&lock, flags);
  5303. + return ret;
  5304. +}
  5305. +EXPORT_SYMBOL_GPL(rb750_latch_change);
  5306. +
  5307. +static void __init rb750_setup(void)
  5308. +{
  5309. + ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
  5310. + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
  5311. + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
  5312. + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
  5313. + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
  5314. +
  5315. + ap91_eth_init(NULL, rb750_port_names);
  5316. + platform_device_register(&rb750_leds_device);
  5317. + platform_device_register(&rb750_nand_device);
  5318. +}
  5319. +
  5320. +MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750",
  5321. + rb750_setup);
  5322. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.36/arch/mips/ar71xx/mach-tew-632brp.c
  5323. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100
  5324. +++ linux-2.6.36/arch/mips/ar71xx/mach-tew-632brp.c 2010-12-17 18:34:51.000000000 +0100
  5325. @@ -0,0 +1,149 @@
  5326. +/*
  5327. + * TrendNET TEW-632BRP board support
  5328. + *
  5329. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  5330. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5331. + *
  5332. + * This program is free software; you can redistribute it and/or modify it
  5333. + * under the terms of the GNU General Public License version 2 as published
  5334. + * by the Free Software Foundation.
  5335. + */
  5336. +
  5337. +#include <linux/mtd/mtd.h>
  5338. +#include <linux/mtd/partitions.h>
  5339. +
  5340. +#include <asm/mach-ar71xx/ar71xx.h>
  5341. +
  5342. +#include "machtype.h"
  5343. +#include "devices.h"
  5344. +#include "dev-m25p80.h"
  5345. +#include "dev-ar913x-wmac.h"
  5346. +#include "dev-gpio-buttons.h"
  5347. +#include "dev-leds-gpio.h"
  5348. +#include "nvram.h"
  5349. +
  5350. +#define TEW_632BRP_GPIO_LED_STATUS 1
  5351. +#define TEW_632BRP_GPIO_LED_WPS 3
  5352. +#define TEW_632BRP_GPIO_LED_WLAN 6
  5353. +#define TEW_632BRP_GPIO_BTN_WPS 12
  5354. +#define TEW_632BRP_GPIO_BTN_RESET 21
  5355. +
  5356. +#define TEW_632BRP_BUTTONS_POLL_INTERVAL 20
  5357. +
  5358. +#define TEW_632BRP_CONFIG_ADDR 0x1f020000
  5359. +#define TEW_632BRP_CONFIG_SIZE 0x10000
  5360. +
  5361. +#ifdef CONFIG_MTD_PARTITIONS
  5362. +static struct mtd_partition tew_632brp_partitions[] = {
  5363. + {
  5364. + .name = "u-boot",
  5365. + .offset = 0,
  5366. + .size = 0x020000,
  5367. + .mask_flags = MTD_WRITEABLE,
  5368. + } , {
  5369. + .name = "config",
  5370. + .offset = 0x020000,
  5371. + .size = 0x010000,
  5372. + } , {
  5373. + .name = "kernel",
  5374. + .offset = 0x030000,
  5375. + .size = 0x0d0000,
  5376. + } , {
  5377. + .name = "rootfs",
  5378. + .offset = 0x100000,
  5379. + .size = 0x2f0000,
  5380. + } , {
  5381. + .name = "art",
  5382. + .offset = 0x3f0000,
  5383. + .size = 0x010000,
  5384. + .mask_flags = MTD_WRITEABLE,
  5385. + } , {
  5386. + .name = "firmware",
  5387. + .offset = 0x030000,
  5388. + .size = 0x3c0000,
  5389. + }
  5390. +};
  5391. +#endif /* CONFIG_MTD_PARTITIONS */
  5392. +
  5393. +static struct flash_platform_data tew_632brp_flash_data = {
  5394. +#ifdef CONFIG_MTD_PARTITIONS
  5395. + .parts = tew_632brp_partitions,
  5396. + .nr_parts = ARRAY_SIZE(tew_632brp_partitions),
  5397. +#endif
  5398. +};
  5399. +
  5400. +static struct gpio_led tew_632brp_leds_gpio[] __initdata = {
  5401. + {
  5402. + .name = "tew-632brp:green:status",
  5403. + .gpio = TEW_632BRP_GPIO_LED_STATUS,
  5404. + .active_low = 1,
  5405. + }, {
  5406. + .name = "tew-632brp:blue:wps",
  5407. + .gpio = TEW_632BRP_GPIO_LED_WPS,
  5408. + .active_low = 1,
  5409. + }, {
  5410. + .name = "tew-632brp:green:wlan",
  5411. + .gpio = TEW_632BRP_GPIO_LED_WLAN,
  5412. + .active_low = 1,
  5413. + }
  5414. +};
  5415. +
  5416. +static struct gpio_button tew_632brp_gpio_buttons[] __initdata = {
  5417. + {
  5418. + .desc = "reset",
  5419. + .type = EV_KEY,
  5420. + .code = KEY_RESTART,
  5421. + .threshold = 3,
  5422. + .gpio = TEW_632BRP_GPIO_BTN_RESET,
  5423. + }, {
  5424. + .desc = "wps",
  5425. + .type = EV_KEY,
  5426. + .code = KEY_WPS_BUTTON,
  5427. + .threshold = 3,
  5428. + .gpio = TEW_632BRP_GPIO_BTN_WPS,
  5429. + }
  5430. +};
  5431. +
  5432. +#define TEW_632BRP_LAN_PHYMASK BIT(0)
  5433. +#define TEW_632BRP_WAN_PHYMASK BIT(4)
  5434. +#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \
  5435. + TEW_632BRP_WAN_PHYMASK))
  5436. +
  5437. +static void __init tew_632brp_setup(void)
  5438. +{
  5439. + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR);
  5440. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5441. + u8 mac[6];
  5442. + u8 *wlan_mac = NULL;
  5443. +
  5444. + if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE,
  5445. + "lan_mac=", mac) == 0) {
  5446. + ar71xx_set_mac_base(mac);
  5447. + wlan_mac = mac;
  5448. + }
  5449. +
  5450. + ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK);
  5451. +
  5452. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5453. + ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK;
  5454. +
  5455. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5456. + ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK;
  5457. +
  5458. + ar71xx_add_device_eth(0);
  5459. + ar71xx_add_device_eth(1);
  5460. +
  5461. + ar71xx_add_device_m25p80(&tew_632brp_flash_data);
  5462. +
  5463. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio),
  5464. + tew_632brp_leds_gpio);
  5465. +
  5466. + ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL,
  5467. + ARRAY_SIZE(tew_632brp_gpio_buttons),
  5468. + tew_632brp_gpio_buttons);
  5469. +
  5470. + ar913x_add_device_wmac(eeprom, wlan_mac);
  5471. +}
  5472. +
  5473. +MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP",
  5474. + tew_632brp_setup);
  5475. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.36/arch/mips/ar71xx/mach-tl-wr1043nd.c
  5476. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100
  5477. +++ linux-2.6.36/arch/mips/ar71xx/mach-tl-wr1043nd.c 2010-12-17 18:34:51.000000000 +0100
  5478. @@ -0,0 +1,156 @@
  5479. +/*
  5480. + * TP-LINK TL-WR1043ND board support
  5481. + *
  5482. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5483. + *
  5484. + * This program is free software; you can redistribute it and/or modify it
  5485. + * under the terms of the GNU General Public License version 2 as published
  5486. + * by the Free Software Foundation.
  5487. + */
  5488. +
  5489. +#include <linux/mtd/mtd.h>
  5490. +#include <linux/mtd/partitions.h>
  5491. +#include <linux/platform_device.h>
  5492. +#include <linux/rtl8366rb.h>
  5493. +#include <asm/mach-ar71xx/ar71xx.h>
  5494. +
  5495. +#include "machtype.h"
  5496. +#include "devices.h"
  5497. +#include "dev-m25p80.h"
  5498. +#include "dev-ar913x-wmac.h"
  5499. +#include "dev-gpio-buttons.h"
  5500. +#include "dev-leds-gpio.h"
  5501. +#include "dev-usb.h"
  5502. +
  5503. +#define TL_WR1043ND_GPIO_LED_USB 1
  5504. +#define TL_WR1043ND_GPIO_LED_SYSTEM 2
  5505. +#define TL_WR1043ND_GPIO_LED_QSS 5
  5506. +#define TL_WR1043ND_GPIO_LED_WLAN 9
  5507. +
  5508. +#define TL_WR1043ND_GPIO_BTN_RESET 3
  5509. +#define TL_WR1043ND_GPIO_BTN_QSS 7
  5510. +
  5511. +#define TL_WR1043ND_GPIO_RTL8366_SDA 18
  5512. +#define TL_WR1043ND_GPIO_RTL8366_SCK 19
  5513. +
  5514. +#define TL_WR1043ND_BUTTONS_POLL_INTERVAL 20
  5515. +
  5516. +#ifdef CONFIG_MTD_PARTITIONS
  5517. +static struct mtd_partition tl_wr1043nd_partitions[] = {
  5518. + {
  5519. + .name = "u-boot",
  5520. + .offset = 0,
  5521. + .size = 0x020000,
  5522. + .mask_flags = MTD_WRITEABLE,
  5523. + } , {
  5524. + .name = "kernel",
  5525. + .offset = 0x020000,
  5526. + .size = 0x140000,
  5527. + } , {
  5528. + .name = "rootfs",
  5529. + .offset = 0x160000,
  5530. + .size = 0x690000,
  5531. + } , {
  5532. + .name = "art",
  5533. + .offset = 0x7f0000,
  5534. + .size = 0x010000,
  5535. + .mask_flags = MTD_WRITEABLE,
  5536. + } , {
  5537. + .name = "firmware",
  5538. + .offset = 0x020000,
  5539. + .size = 0x7d0000,
  5540. + }
  5541. +};
  5542. +#endif /* CONFIG_MTD_PARTITIONS */
  5543. +
  5544. +static struct flash_platform_data tl_wr1043nd_flash_data = {
  5545. +#ifdef CONFIG_MTD_PARTITIONS
  5546. + .parts = tl_wr1043nd_partitions,
  5547. + .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions),
  5548. +#endif
  5549. +};
  5550. +
  5551. +static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
  5552. + {
  5553. + .name = "tl-wr1043nd:green:usb",
  5554. + .gpio = TL_WR1043ND_GPIO_LED_USB,
  5555. + .active_low = 1,
  5556. + }, {
  5557. + .name = "tl-wr1043nd:green:system",
  5558. + .gpio = TL_WR1043ND_GPIO_LED_SYSTEM,
  5559. + .active_low = 1,
  5560. + }, {
  5561. + .name = "tl-wr1043nd:green:qss",
  5562. + .gpio = TL_WR1043ND_GPIO_LED_QSS,
  5563. + .active_low = 0,
  5564. + }, {
  5565. + .name = "tl-wr1043nd:green:wlan",
  5566. + .gpio = TL_WR1043ND_GPIO_LED_WLAN,
  5567. + .active_low = 1,
  5568. + }
  5569. +};
  5570. +
  5571. +static struct gpio_button tl_wr1043nd_gpio_buttons[] __initdata = {
  5572. + {
  5573. + .desc = "reset",
  5574. + .type = EV_KEY,
  5575. + .code = KEY_RESTART,
  5576. + .threshold = 3,
  5577. + .gpio = TL_WR1043ND_GPIO_BTN_RESET,
  5578. + .active_low = 1,
  5579. + }, {
  5580. + .desc = "qss",
  5581. + .type = EV_KEY,
  5582. + .code = KEY_WPS_BUTTON,
  5583. + .threshold = 3,
  5584. + .gpio = TL_WR1043ND_GPIO_BTN_QSS,
  5585. + .active_low = 1,
  5586. + }
  5587. +};
  5588. +
  5589. +static struct rtl8366rb_platform_data tl_wr1043nd_rtl8366rb_data = {
  5590. + .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA,
  5591. + .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK,
  5592. +};
  5593. +
  5594. +static struct platform_device tl_wr1043nd_rtl8366rb_device = {
  5595. + .name = RTL8366RB_DRIVER_NAME,
  5596. + .id = -1,
  5597. + .dev = {
  5598. + .platform_data = &tl_wr1043nd_rtl8366rb_data,
  5599. + }
  5600. +};
  5601. +
  5602. +static void __init tl_wr1043nd_setup(void)
  5603. +{
  5604. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5605. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5606. +
  5607. + ar71xx_set_mac_base(mac);
  5608. +
  5609. + ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev;
  5610. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5611. + ar71xx_eth0_data.speed = SPEED_1000;
  5612. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5613. + ar71xx_eth0_pll_data.pll_1000 = 0x1a000000;
  5614. +
  5615. + ar71xx_add_device_eth(0);
  5616. +
  5617. + ar71xx_add_device_usb();
  5618. +
  5619. + ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data);
  5620. +
  5621. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio),
  5622. + tl_wr1043nd_leds_gpio);
  5623. +
  5624. + platform_device_register(&tl_wr1043nd_rtl8366rb_device);
  5625. +
  5626. + ar71xx_add_device_gpio_buttons(-1, TL_WR1043ND_BUTTONS_POLL_INTERVAL,
  5627. + ARRAY_SIZE(tl_wr1043nd_gpio_buttons),
  5628. + tl_wr1043nd_gpio_buttons);
  5629. +
  5630. + ar913x_add_device_wmac(eeprom, mac);
  5631. +}
  5632. +
  5633. +MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND",
  5634. + tl_wr1043nd_setup);
  5635. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.36/arch/mips/ar71xx/mach-tl-wr741nd.c
  5636. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100
  5637. +++ linux-2.6.36/arch/mips/ar71xx/mach-tl-wr741nd.c 2010-12-17 18:34:51.000000000 +0100
  5638. @@ -0,0 +1,115 @@
  5639. +/*
  5640. + * TP-LINK TL-WR741ND board support
  5641. + *
  5642. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5643. + *
  5644. + * This program is free software; you can redistribute it and/or modify it
  5645. + * under the terms of the GNU General Public License version 2 as published
  5646. + * by the Free Software Foundation.
  5647. + */
  5648. +
  5649. +#include <linux/mtd/mtd.h>
  5650. +#include <linux/mtd/partitions.h>
  5651. +
  5652. +#include <asm/mach-ar71xx/ar71xx.h>
  5653. +
  5654. +#include "machtype.h"
  5655. +#include "devices.h"
  5656. +#include "dev-m25p80.h"
  5657. +#include "dev-ap91-eth.h"
  5658. +#include "dev-ap91-pci.h"
  5659. +#include "dev-gpio-buttons.h"
  5660. +#include "dev-leds-gpio.h"
  5661. +
  5662. +#define TL_WR741ND_GPIO_LED_QSS 0
  5663. +#define TL_WR741ND_GPIO_LED_SYSTEM 1
  5664. +
  5665. +#define TL_WR741ND_GPIO_BTN_RESET 11
  5666. +#define TL_WR741ND_GPIO_BTN_QSS 12
  5667. +
  5668. +#define TL_WR741ND_BUTTONS_POLL_INTERVAL 20
  5669. +
  5670. +#ifdef CONFIG_MTD_PARTITIONS
  5671. +static struct mtd_partition tl_wr741nd_partitions[] = {
  5672. + {
  5673. + .name = "u-boot",
  5674. + .offset = 0,
  5675. + .size = 0x020000,
  5676. + .mask_flags = MTD_WRITEABLE,
  5677. + } , {
  5678. + .name = "kernel",
  5679. + .offset = 0x020000,
  5680. + .size = 0x140000,
  5681. + } , {
  5682. + .name = "rootfs",
  5683. + .offset = 0x160000,
  5684. + .size = 0x290000,
  5685. + } , {
  5686. + .name = "art",
  5687. + .offset = 0x3f0000,
  5688. + .size = 0x010000,
  5689. + .mask_flags = MTD_WRITEABLE,
  5690. + } , {
  5691. + .name = "firmware",
  5692. + .offset = 0x020000,
  5693. + .size = 0x3d0000,
  5694. + }
  5695. +};
  5696. +#endif /* CONFIG_MTD_PARTITIONS */
  5697. +
  5698. +static struct flash_platform_data tl_wr741nd_flash_data = {
  5699. +#ifdef CONFIG_MTD_PARTITIONS
  5700. + .parts = tl_wr741nd_partitions,
  5701. + .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions),
  5702. +#endif
  5703. +};
  5704. +
  5705. +static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = {
  5706. + {
  5707. + .name = "tl-wr741nd:green:system",
  5708. + .gpio = TL_WR741ND_GPIO_LED_SYSTEM,
  5709. + .active_low = 1,
  5710. + }, {
  5711. + .name = "tl-wr741nd:green:qss",
  5712. + .gpio = TL_WR741ND_GPIO_LED_QSS,
  5713. + .active_low = 1,
  5714. + }
  5715. +};
  5716. +
  5717. +static struct gpio_button tl_wr741nd_gpio_buttons[] __initdata = {
  5718. + {
  5719. + .desc = "reset",
  5720. + .type = EV_KEY,
  5721. + .code = KEY_RESTART,
  5722. + .threshold = 3,
  5723. + .gpio = TL_WR741ND_GPIO_BTN_RESET,
  5724. + .active_low = 1,
  5725. + }, {
  5726. + .desc = "qss",
  5727. + .type = EV_KEY,
  5728. + .code = KEY_WPS_BUTTON,
  5729. + .threshold = 3,
  5730. + .gpio = TL_WR741ND_GPIO_BTN_QSS,
  5731. + .active_low = 1,
  5732. + }
  5733. +};
  5734. +
  5735. +static void __init tl_wr741nd_setup(void)
  5736. +{
  5737. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5738. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  5739. +
  5740. + ar71xx_add_device_m25p80(&tl_wr741nd_flash_data);
  5741. +
  5742. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio),
  5743. + tl_wr741nd_leds_gpio);
  5744. +
  5745. + ar71xx_add_device_gpio_buttons(-1, TL_WR741ND_BUTTONS_POLL_INTERVAL,
  5746. + ARRAY_SIZE(tl_wr741nd_gpio_buttons),
  5747. + tl_wr741nd_gpio_buttons);
  5748. +
  5749. + ap91_eth_init(mac, NULL);
  5750. + ap91_pci_init(ee, mac);
  5751. +}
  5752. +MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND",
  5753. + tl_wr741nd_setup);
  5754. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.36/arch/mips/ar71xx/mach-tl-wr841n.c
  5755. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100
  5756. +++ linux-2.6.36/arch/mips/ar71xx/mach-tl-wr841n.c 2010-12-17 18:34:51.000000000 +0100
  5757. @@ -0,0 +1,143 @@
  5758. +/*
  5759. + * TP-LINK TL-WR841N board support
  5760. + *
  5761. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5762. + *
  5763. + * This program is free software; you can redistribute it and/or modify it
  5764. + * under the terms of the GNU General Public License version 2 as published
  5765. + * by the Free Software Foundation.
  5766. + */
  5767. +
  5768. +#include <linux/mtd/mtd.h>
  5769. +#include <linux/mtd/partitions.h>
  5770. +
  5771. +#include <asm/mach-ar71xx/ar71xx.h>
  5772. +
  5773. +#include "machtype.h"
  5774. +#include "devices.h"
  5775. +#include "dev-dsa.h"
  5776. +#include "dev-m25p80.h"
  5777. +#include "dev-gpio-buttons.h"
  5778. +#include "dev-pb42-pci.h"
  5779. +#include "dev-leds-gpio.h"
  5780. +
  5781. +#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2
  5782. +#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4
  5783. +#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5
  5784. +
  5785. +#define TL_WR841ND_V1_GPIO_BTN_RESET 3
  5786. +#define TL_WR841ND_V1_GPIO_BTN_QSS 7
  5787. +
  5788. +#define TL_WR841ND_V1_BUTTONS_POLL_INTERVAL 20
  5789. +
  5790. +#ifdef CONFIG_MTD_PARTITIONS
  5791. +static struct mtd_partition tl_wr841n_v1_partitions[] = {
  5792. + {
  5793. + .name = "redboot",
  5794. + .offset = 0,
  5795. + .size = 0x020000,
  5796. + .mask_flags = MTD_WRITEABLE,
  5797. + } , {
  5798. + .name = "kernel",
  5799. + .offset = 0x020000,
  5800. + .size = 0x140000,
  5801. + } , {
  5802. + .name = "rootfs",
  5803. + .offset = 0x160000,
  5804. + .size = 0x280000,
  5805. + } , {
  5806. + .name = "config",
  5807. + .offset = 0x3e0000,
  5808. + .size = 0x020000,
  5809. + .mask_flags = MTD_WRITEABLE,
  5810. + } , {
  5811. + .name = "firmware",
  5812. + .offset = 0x020000,
  5813. + .size = 0x3c0000,
  5814. + }
  5815. +};
  5816. +#endif /* CONFIG_MTD_PARTITIONS */
  5817. +
  5818. +static struct flash_platform_data tl_wr841n_v1_flash_data = {
  5819. +#ifdef CONFIG_MTD_PARTITIONS
  5820. + .parts = tl_wr841n_v1_partitions,
  5821. + .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions),
  5822. +#endif
  5823. +};
  5824. +
  5825. +static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = {
  5826. + {
  5827. + .name = "tl-wr841n:green:system",
  5828. + .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM,
  5829. + .active_low = 1,
  5830. + }, {
  5831. + .name = "tl-wr841n:red:qss",
  5832. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED,
  5833. + }, {
  5834. + .name = "tl-wr841n:green:qss",
  5835. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN,
  5836. + }
  5837. +};
  5838. +
  5839. +static struct gpio_button tl_wr841n_v1_gpio_buttons[] __initdata = {
  5840. + {
  5841. + .desc = "reset",
  5842. + .type = EV_KEY,
  5843. + .code = KEY_RESTART,
  5844. + .threshold = 3,
  5845. + .gpio = TL_WR841ND_V1_GPIO_BTN_RESET,
  5846. + .active_low = 1,
  5847. + }, {
  5848. + .desc = "qss",
  5849. + .type = EV_KEY,
  5850. + .code = KEY_WPS_BUTTON,
  5851. + .threshold = 3,
  5852. + .gpio = TL_WR841ND_V1_GPIO_BTN_QSS,
  5853. + .active_low = 1,
  5854. + }
  5855. +};
  5856. +
  5857. +static struct dsa_chip_data tl_wr841n_v1_dsa_chip = {
  5858. + .port_names[0] = "wan",
  5859. + .port_names[1] = "lan1",
  5860. + .port_names[2] = "lan2",
  5861. + .port_names[3] = "lan3",
  5862. + .port_names[4] = "lan4",
  5863. + .port_names[5] = "cpu",
  5864. +};
  5865. +
  5866. +static struct dsa_platform_data tl_wr841n_v1_dsa_data = {
  5867. + .nr_chips = 1,
  5868. + .chip = &tl_wr841n_v1_dsa_chip,
  5869. +};
  5870. +
  5871. +static void __init tl_wr841n_v1_setup(void)
  5872. +{
  5873. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5874. +
  5875. + ar71xx_set_mac_base(mac);
  5876. +
  5877. + ar71xx_add_device_mdio(0x0);
  5878. +
  5879. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5880. + ar71xx_eth0_data.speed = SPEED_100;
  5881. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5882. +
  5883. + ar71xx_add_device_eth(0);
  5884. +
  5885. + ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data);
  5886. +
  5887. + ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data);
  5888. +
  5889. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio),
  5890. + tl_wr841n_v1_leds_gpio);
  5891. +
  5892. + ar71xx_add_device_gpio_buttons(-1, TL_WR841ND_V1_BUTTONS_POLL_INTERVAL,
  5893. + ARRAY_SIZE(tl_wr841n_v1_gpio_buttons),
  5894. + tl_wr841n_v1_gpio_buttons);
  5895. +
  5896. + pb42_pci_init();
  5897. +}
  5898. +
  5899. +MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1",
  5900. + tl_wr841n_v1_setup);
  5901. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.36/arch/mips/ar71xx/mach-tl-wr941nd.c
  5902. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100
  5903. +++ linux-2.6.36/arch/mips/ar71xx/mach-tl-wr941nd.c 2010-12-17 18:34:51.000000000 +0100
  5904. @@ -0,0 +1,142 @@
  5905. +/*
  5906. + * TP-LINK TL-WR941ND board support
  5907. + *
  5908. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5909. + *
  5910. + * This program is free software; you can redistribute it and/or modify it
  5911. + * under the terms of the GNU General Public License version 2 as published
  5912. + * by the Free Software Foundation.
  5913. + */
  5914. +
  5915. +#include <linux/mtd/mtd.h>
  5916. +#include <linux/mtd/partitions.h>
  5917. +
  5918. +#include <asm/mach-ar71xx/ar71xx.h>
  5919. +
  5920. +#include "machtype.h"
  5921. +#include "devices.h"
  5922. +#include "dev-dsa.h"
  5923. +#include "dev-m25p80.h"
  5924. +#include "dev-ar913x-wmac.h"
  5925. +#include "dev-gpio-buttons.h"
  5926. +#include "dev-leds-gpio.h"
  5927. +
  5928. +#define TL_WR941ND_GPIO_LED_SYSTEM 2
  5929. +#define TL_WR941ND_GPIO_LED_QSS_RED 4
  5930. +#define TL_WR941ND_GPIO_LED_QSS_GREEN 5
  5931. +
  5932. +#define TL_WR941ND_GPIO_BTN_RESET 3
  5933. +#define TL_WR941ND_GPIO_BTN_QSS 7
  5934. +
  5935. +#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20
  5936. +
  5937. +#ifdef CONFIG_MTD_PARTITIONS
  5938. +static struct mtd_partition tl_wr941nd_partitions[] = {
  5939. + {
  5940. + .name = "u-boot",
  5941. + .offset = 0,
  5942. + .size = 0x020000,
  5943. + .mask_flags = MTD_WRITEABLE,
  5944. + } , {
  5945. + .name = "kernel",
  5946. + .offset = 0x020000,
  5947. + .size = 0x140000,
  5948. + } , {
  5949. + .name = "rootfs",
  5950. + .offset = 0x160000,
  5951. + .size = 0x290000,
  5952. + } , {
  5953. + .name = "art",
  5954. + .offset = 0x3f0000,
  5955. + .size = 0x010000,
  5956. + .mask_flags = MTD_WRITEABLE,
  5957. + } , {
  5958. + .name = "firmware",
  5959. + .offset = 0x020000,
  5960. + .size = 0x3d0000,
  5961. + }
  5962. +};
  5963. +#endif /* CONFIG_MTD_PARTITIONS */
  5964. +
  5965. +static struct flash_platform_data tl_wr941nd_flash_data = {
  5966. +#ifdef CONFIG_MTD_PARTITIONS
  5967. + .parts = tl_wr941nd_partitions,
  5968. + .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions),
  5969. +#endif
  5970. +};
  5971. +
  5972. +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = {
  5973. + {
  5974. + .name = "tl-wr941nd:green:system",
  5975. + .gpio = TL_WR941ND_GPIO_LED_SYSTEM,
  5976. + .active_low = 1,
  5977. + }, {
  5978. + .name = "tl-wr941nd:red:qss",
  5979. + .gpio = TL_WR941ND_GPIO_LED_QSS_RED,
  5980. + }, {
  5981. + .name = "tl-wr941nd:green:qss",
  5982. + .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN,
  5983. + }
  5984. +};
  5985. +
  5986. +static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = {
  5987. + {
  5988. + .desc = "reset",
  5989. + .type = EV_KEY,
  5990. + .code = KEY_RESTART,
  5991. + .threshold = 3,
  5992. + .gpio = TL_WR941ND_GPIO_BTN_RESET,
  5993. + .active_low = 1,
  5994. + }, {
  5995. + .desc = "qss",
  5996. + .type = EV_KEY,
  5997. + .code = KEY_WPS_BUTTON,
  5998. + .threshold = 3,
  5999. + .gpio = TL_WR941ND_GPIO_BTN_QSS,
  6000. + .active_low = 1,
  6001. + }
  6002. +};
  6003. +
  6004. +static struct dsa_chip_data tl_wr941nd_dsa_chip = {
  6005. + .port_names[0] = "wan",
  6006. + .port_names[1] = "lan1",
  6007. + .port_names[2] = "lan2",
  6008. + .port_names[3] = "lan3",
  6009. + .port_names[4] = "lan4",
  6010. + .port_names[5] = "cpu",
  6011. +};
  6012. +
  6013. +static struct dsa_platform_data tl_wr941nd_dsa_data = {
  6014. + .nr_chips = 1,
  6015. + .chip = &tl_wr941nd_dsa_chip,
  6016. +};
  6017. +
  6018. +static void __init tl_wr941nd_setup(void)
  6019. +{
  6020. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  6021. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6022. +
  6023. + ar71xx_set_mac_base(mac);
  6024. +
  6025. + ar71xx_add_device_mdio(0x0);
  6026. +
  6027. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6028. + ar71xx_eth0_data.speed = SPEED_100;
  6029. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6030. +
  6031. + ar71xx_add_device_eth(0);
  6032. + ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data);
  6033. +
  6034. + ar71xx_add_device_m25p80(&tl_wr941nd_flash_data);
  6035. +
  6036. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio),
  6037. + tl_wr941nd_leds_gpio);
  6038. +
  6039. + ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL,
  6040. + ARRAY_SIZE(tl_wr941nd_gpio_buttons),
  6041. + tl_wr941nd_gpio_buttons);
  6042. + ar913x_add_device_wmac(eeprom, mac);
  6043. +}
  6044. +
  6045. +MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND",
  6046. + tl_wr941nd_setup);
  6047. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.36/arch/mips/ar71xx/mach-ubnt.c
  6048. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100
  6049. +++ linux-2.6.36/arch/mips/ar71xx/mach-ubnt.c 2010-12-17 18:34:51.000000000 +0100
  6050. @@ -0,0 +1,281 @@
  6051. +/*
  6052. + * Ubiquiti RouterStation support
  6053. + *
  6054. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6055. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6056. + * Copyright (C) 2008 Ubiquiti <support@ubnt.com>
  6057. + *
  6058. + * This program is free software; you can redistribute it and/or modify it
  6059. + * under the terms of the GNU General Public License version 2 as published
  6060. + * by the Free Software Foundation.
  6061. + */
  6062. +
  6063. +#include <asm/mach-ar71xx/ar71xx.h>
  6064. +
  6065. +#include "machtype.h"
  6066. +#include "devices.h"
  6067. +#include "dev-m25p80.h"
  6068. +#include "dev-ap91-pci.h"
  6069. +#include "dev-gpio-buttons.h"
  6070. +#include "dev-pb42-pci.h"
  6071. +#include "dev-leds-gpio.h"
  6072. +#include "dev-usb.h"
  6073. +
  6074. +#define UBNT_RS_GPIO_LED_RF 2
  6075. +#define UBNT_RS_GPIO_SW4 8
  6076. +
  6077. +#define UBNT_LS_SR71_GPIO_LED_D25 0
  6078. +#define UBNT_LS_SR71_GPIO_LED_D26 1
  6079. +#define UBNT_LS_SR71_GPIO_LED_D24 2
  6080. +#define UBNT_LS_SR71_GPIO_LED_D23 4
  6081. +#define UBNT_LS_SR71_GPIO_LED_D22 5
  6082. +#define UBNT_LS_SR71_GPIO_LED_D27 6
  6083. +#define UBNT_LS_SR71_GPIO_LED_D28 7
  6084. +
  6085. +#define UBNT_M_GPIO_LED_L1 0
  6086. +#define UBNT_M_GPIO_LED_L2 1
  6087. +#define UBNT_M_GPIO_LED_L3 11
  6088. +#define UBNT_M_GPIO_LED_L4 7
  6089. +#define UBNT_M_GPIO_BTN_RESET 12
  6090. +
  6091. +#define UBNT_BUTTONS_POLL_INTERVAL 20
  6092. +
  6093. +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = {
  6094. + {
  6095. + .name = "ubnt:green:rf",
  6096. + .gpio = UBNT_RS_GPIO_LED_RF,
  6097. + .active_low = 0,
  6098. + }
  6099. +};
  6100. +
  6101. +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = {
  6102. + {
  6103. + .name = "ubnt:green:d22",
  6104. + .gpio = UBNT_LS_SR71_GPIO_LED_D22,
  6105. + .active_low = 0,
  6106. + }, {
  6107. + .name = "ubnt:green:d23",
  6108. + .gpio = UBNT_LS_SR71_GPIO_LED_D23,
  6109. + .active_low = 0,
  6110. + }, {
  6111. + .name = "ubnt:green:d24",
  6112. + .gpio = UBNT_LS_SR71_GPIO_LED_D24,
  6113. + .active_low = 0,
  6114. + }, {
  6115. + .name = "ubnt:red:d25",
  6116. + .gpio = UBNT_LS_SR71_GPIO_LED_D25,
  6117. + .active_low = 0,
  6118. + }, {
  6119. + .name = "ubnt:red:d26",
  6120. + .gpio = UBNT_LS_SR71_GPIO_LED_D26,
  6121. + .active_low = 0,
  6122. + }, {
  6123. + .name = "ubnt:green:d27",
  6124. + .gpio = UBNT_LS_SR71_GPIO_LED_D27,
  6125. + .active_low = 0,
  6126. + }, {
  6127. + .name = "ubnt:green:d28",
  6128. + .gpio = UBNT_LS_SR71_GPIO_LED_D28,
  6129. + .active_low = 0,
  6130. + }
  6131. +};
  6132. +
  6133. +static struct gpio_led ubnt_m_leds_gpio[] __initdata = {
  6134. + {
  6135. + .name = "ubnt:red:link1",
  6136. + .gpio = UBNT_M_GPIO_LED_L1,
  6137. + .active_low = 0,
  6138. + }, {
  6139. + .name = "ubnt:orange:link2",
  6140. + .gpio = UBNT_M_GPIO_LED_L2,
  6141. + .active_low = 0,
  6142. + }, {
  6143. + .name = "ubnt:green:link3",
  6144. + .gpio = UBNT_M_GPIO_LED_L3,
  6145. + .active_low = 0,
  6146. + }, {
  6147. + .name = "ubnt:green:link4",
  6148. + .gpio = UBNT_M_GPIO_LED_L4,
  6149. + .active_low = 0,
  6150. + }
  6151. +};
  6152. +
  6153. +static struct gpio_button ubnt_gpio_buttons[] __initdata = {
  6154. + {
  6155. + .desc = "sw4",
  6156. + .type = EV_KEY,
  6157. + .code = KEY_RESTART,
  6158. + .threshold = 3,
  6159. + .gpio = UBNT_RS_GPIO_SW4,
  6160. + .active_low = 1,
  6161. + }
  6162. +};
  6163. +
  6164. +static struct gpio_button ubnt_m_gpio_buttons[] __initdata = {
  6165. + {
  6166. + .desc = "reset",
  6167. + .type = EV_KEY,
  6168. + .code = KEY_RESTART,
  6169. + .threshold = 3,
  6170. + .gpio = UBNT_M_GPIO_BTN_RESET,
  6171. + .active_low = 1,
  6172. + }
  6173. +};
  6174. +
  6175. +static void __init ubnt_generic_setup(void)
  6176. +{
  6177. + ar71xx_add_device_m25p80(NULL);
  6178. +
  6179. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6180. + ARRAY_SIZE(ubnt_gpio_buttons),
  6181. + ubnt_gpio_buttons);
  6182. +
  6183. + pb42_pci_init();
  6184. +}
  6185. +
  6186. +#define UBNT_RS_WAN_PHYMASK (1 << 20)
  6187. +#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19))
  6188. +
  6189. +static void __init ubnt_rs_setup(void)
  6190. +{
  6191. + ubnt_generic_setup();
  6192. +
  6193. + ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK));
  6194. +
  6195. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6196. + ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK;
  6197. +
  6198. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6199. + ar71xx_eth1_data.speed = SPEED_100;
  6200. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6201. +
  6202. + ar71xx_add_device_eth(0);
  6203. + ar71xx_add_device_eth(1);
  6204. +
  6205. + ar71xx_add_device_usb();
  6206. +
  6207. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6208. + ubnt_rs_leds_gpio);
  6209. +}
  6210. +
  6211. +MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation",
  6212. + ubnt_rs_setup);
  6213. +
  6214. +MIPS_MACHINE(AR71XX_MACH_UBNT_AR71XX, "Ubiquiti AR71xx-based board",
  6215. + "Ubiquiti RouterStation", ubnt_rs_setup);
  6216. +
  6217. +#define UBNT_RSPRO_WAN_PHYMASK (1 << 4)
  6218. +#define UBNT_RSPRO_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
  6219. +
  6220. +static void __init ubnt_rspro_setup(void)
  6221. +{
  6222. + ubnt_generic_setup();
  6223. +
  6224. + ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | UBNT_RSPRO_LAN_PHYMASK));
  6225. +
  6226. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6227. + ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK;
  6228. +
  6229. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6230. + ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK;
  6231. + ar71xx_eth1_data.speed = SPEED_1000;
  6232. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6233. +
  6234. + ar71xx_add_device_eth(0);
  6235. + ar71xx_add_device_eth(1);
  6236. +
  6237. + ar71xx_add_device_usb();
  6238. +
  6239. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6240. + ubnt_rs_leds_gpio);
  6241. +}
  6242. +
  6243. +MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro",
  6244. + ubnt_rspro_setup);
  6245. +
  6246. +static void __init ubnt_lsx_setup(void)
  6247. +{
  6248. + ubnt_generic_setup();
  6249. +}
  6250. +
  6251. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup);
  6252. +
  6253. +#define UBNT_LSSR71_PHY_MASK (1 << 1)
  6254. +
  6255. +static void __init ubnt_lssr71_setup(void)
  6256. +{
  6257. + ubnt_generic_setup();
  6258. +
  6259. + ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK);
  6260. +
  6261. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6262. + ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK;
  6263. +
  6264. + ar71xx_add_device_eth(0);
  6265. +
  6266. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio),
  6267. + ubnt_ls_sr71_leds_gpio);
  6268. +}
  6269. +
  6270. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71",
  6271. + ubnt_lssr71_setup);
  6272. +
  6273. +static void __init ubnt_m_setup(void)
  6274. +{
  6275. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  6276. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  6277. +
  6278. + ar71xx_set_mac_base(mac);
  6279. +
  6280. + ar71xx_add_device_m25p80(NULL);
  6281. +
  6282. + ar71xx_add_device_mdio(~0);
  6283. +
  6284. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6285. + ar71xx_eth0_data.speed = SPEED_100;
  6286. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6287. + ar71xx_eth0_data.fifo_cfg1 = 0x0010ffff;
  6288. + ar71xx_eth0_data.fifo_cfg2 = 0x015500aa;
  6289. + ar71xx_eth0_data.fifo_cfg3 = 0x01f00140;
  6290. +
  6291. + ar71xx_add_device_eth(0);
  6292. +
  6293. + ap91_pci_init(ee, NULL);
  6294. +
  6295. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio),
  6296. + ubnt_m_leds_gpio);
  6297. +
  6298. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6299. + ARRAY_SIZE(ubnt_m_gpio_buttons),
  6300. + ubnt_m_gpio_buttons);
  6301. +}
  6302. +
  6303. +static void __init ubnt_rocket_m_setup(void)
  6304. +{
  6305. + ubnt_m_setup();
  6306. + ar71xx_add_device_usb();
  6307. +}
  6308. +
  6309. +MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M",
  6310. + ubnt_m_setup);
  6311. +MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M",
  6312. + ubnt_rocket_m_setup);
  6313. +
  6314. +/* TODO detect the second ethernet port and use one
  6315. + init function for all Ubiquiti MIMO series products */
  6316. +static void __init ubnt_nano_m_setup(void)
  6317. +{
  6318. + ubnt_m_setup();
  6319. +
  6320. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6321. + ar71xx_eth1_data.speed = SPEED_1000;
  6322. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6323. + ar71xx_eth1_data.fifo_cfg1 = 0x0010ffff;
  6324. + ar71xx_eth1_data.fifo_cfg2 = 0x015500aa;
  6325. + ar71xx_eth1_data.fifo_cfg3 = 0x01f00140;
  6326. +
  6327. + ar71xx_add_device_eth(1);
  6328. +}
  6329. +
  6330. +MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M",
  6331. + ubnt_nano_m_setup);
  6332. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.36/arch/mips/ar71xx/mach-wndr3700.c
  6333. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100
  6334. +++ linux-2.6.36/arch/mips/ar71xx/mach-wndr3700.c 2010-12-17 18:34:51.000000000 +0100
  6335. @@ -0,0 +1,209 @@
  6336. +/*
  6337. + * Netgear WNDR3700 board support
  6338. + *
  6339. + * Copyright (C) 2009 Marco Porsch
  6340. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6341. + *
  6342. + * This program is free software; you can redistribute it and/or modify it
  6343. + * under the terms of the GNU General Public License version 2 as published
  6344. + * by the Free Software Foundation.
  6345. + */
  6346. +
  6347. +#include <linux/platform_device.h>
  6348. +#include <linux/mtd/mtd.h>
  6349. +#include <linux/mtd/partitions.h>
  6350. +#include <linux/delay.h>
  6351. +#include <linux/rtl8366s.h>
  6352. +
  6353. +#include <asm/mach-ar71xx/ar71xx.h>
  6354. +
  6355. +#include "machtype.h"
  6356. +#include "devices.h"
  6357. +#include "dev-m25p80.h"
  6358. +#include "dev-ap94-pci.h"
  6359. +#include "dev-gpio-buttons.h"
  6360. +#include "dev-leds-gpio.h"
  6361. +#include "dev-usb.h"
  6362. +
  6363. +#define WNDR3700_GPIO_LED_WPS_ORANGE 0
  6364. +#define WNDR3700_GPIO_LED_POWER_ORANGE 1
  6365. +#define WNDR3700_GPIO_LED_POWER_GREEN 2
  6366. +#define WNDR3700_GPIO_LED_WPS_GREEN 4
  6367. +#define WNDR3700_GPIO_LED_WAN_GREEN 6
  6368. +
  6369. +#define WNDR3700_GPIO_BTN_WPS 3
  6370. +#define WNDR3700_GPIO_BTN_RESET 8
  6371. +#define WNDR3700_GPIO_BTN_WIFI 11
  6372. +
  6373. +#define WNDR3700_GPIO_RTL8366_SDA 5
  6374. +#define WNDR3700_GPIO_RTL8366_SCK 7
  6375. +
  6376. +#define WNDR3700_BUTTONS_POLL_INTERVAL 20
  6377. +
  6378. +#define WNDR3700_WMAC0_MAC_OFFSET 0
  6379. +#define WNDR3700_WMAC1_MAC_OFFSET 0xc
  6380. +#define WNDR3700_CALDATA0_OFFSET 0x1000
  6381. +#define WNDR3700_CALDATA1_OFFSET 0x5000
  6382. +
  6383. +#ifdef CONFIG_MTD_PARTITIONS
  6384. +static struct mtd_partition wndr3700_partitions[] = {
  6385. + {
  6386. + .name = "uboot",
  6387. + .offset = 0,
  6388. + .size = 0x050000,
  6389. + .mask_flags = MTD_WRITEABLE,
  6390. + } , {
  6391. + .name = "env",
  6392. + .offset = 0x050000,
  6393. + .size = 0x020000,
  6394. + .mask_flags = MTD_WRITEABLE,
  6395. + } , {
  6396. + .name = "rootfs",
  6397. + .offset = 0x070000,
  6398. + .size = 0x720000,
  6399. + } , {
  6400. + .name = "config",
  6401. + .offset = 0x790000,
  6402. + .size = 0x010000,
  6403. + .mask_flags = MTD_WRITEABLE,
  6404. + } , {
  6405. + .name = "config_bak",
  6406. + .offset = 0x7a0000,
  6407. + .size = 0x010000,
  6408. + .mask_flags = MTD_WRITEABLE,
  6409. + } , {
  6410. + .name = "pot",
  6411. + .offset = 0x7b0000,
  6412. + .size = 0x010000,
  6413. + .mask_flags = MTD_WRITEABLE,
  6414. + } , {
  6415. + .name = "traffic_meter",
  6416. + .offset = 0x7c0000,
  6417. + .size = 0x010000,
  6418. + .mask_flags = MTD_WRITEABLE,
  6419. + } , {
  6420. + .name = "language",
  6421. + .offset = 0x7d0000,
  6422. + .size = 0x020000,
  6423. + .mask_flags = MTD_WRITEABLE,
  6424. + } , {
  6425. + .name = "caldata",
  6426. + .offset = 0x7f0000,
  6427. + .size = 0x010000,
  6428. + .mask_flags = MTD_WRITEABLE,
  6429. + }
  6430. +};
  6431. +#endif /* CONFIG_MTD_PARTITIONS */
  6432. +
  6433. +static struct flash_platform_data wndr3700_flash_data = {
  6434. +#ifdef CONFIG_MTD_PARTITIONS
  6435. + .parts = wndr3700_partitions,
  6436. + .nr_parts = ARRAY_SIZE(wndr3700_partitions),
  6437. +#endif
  6438. +};
  6439. +
  6440. +static struct gpio_led wndr3700_leds_gpio[] __initdata = {
  6441. + {
  6442. + .name = "wndr3700:green:power",
  6443. + .gpio = WNDR3700_GPIO_LED_POWER_GREEN,
  6444. + .active_low = 1,
  6445. + }, {
  6446. + .name = "wndr3700:orange:power",
  6447. + .gpio = WNDR3700_GPIO_LED_POWER_ORANGE,
  6448. + .active_low = 1,
  6449. + }, {
  6450. + .name = "wndr3700:green:wps",
  6451. + .gpio = WNDR3700_GPIO_LED_WPS_GREEN,
  6452. + .active_low = 1,
  6453. + }, {
  6454. + .name = "wndr3700:orange:wps",
  6455. + .gpio = WNDR3700_GPIO_LED_WPS_ORANGE,
  6456. + .active_low = 1,
  6457. + }, {
  6458. + .name = "wndr3700:green:wan",
  6459. + .gpio = WNDR3700_GPIO_LED_WAN_GREEN,
  6460. + .active_low = 1,
  6461. + }
  6462. +};
  6463. +
  6464. +static struct gpio_button wndr3700_gpio_buttons[] __initdata = {
  6465. + {
  6466. + .desc = "reset",
  6467. + .type = EV_KEY,
  6468. + .code = KEY_RESTART,
  6469. + .threshold = 3,
  6470. + .gpio = WNDR3700_GPIO_BTN_RESET,
  6471. + .active_low = 1,
  6472. + }, {
  6473. + .desc = "wps",
  6474. + .type = EV_KEY,
  6475. + .code = KEY_WPS_BUTTON,
  6476. + .threshold = 3,
  6477. + .gpio = WNDR3700_GPIO_BTN_WPS,
  6478. + .active_low = 1,
  6479. + } , {
  6480. + .desc = "wifi",
  6481. + .type = EV_KEY,
  6482. + .code = BTN_2,
  6483. + .threshold = 3,
  6484. + .gpio = WNDR3700_GPIO_BTN_WIFI,
  6485. + .active_low = 1,
  6486. + }
  6487. +};
  6488. +
  6489. +static struct rtl8366s_platform_data wndr3700_rtl8366s_data = {
  6490. + .gpio_sda = WNDR3700_GPIO_RTL8366_SDA,
  6491. + .gpio_sck = WNDR3700_GPIO_RTL8366_SCK,
  6492. +};
  6493. +
  6494. +static struct platform_device wndr3700_rtl8366s_device = {
  6495. + .name = RTL8366S_DRIVER_NAME,
  6496. + .id = -1,
  6497. + .dev = {
  6498. + .platform_data = &wndr3700_rtl8366s_data,
  6499. + }
  6500. +};
  6501. +
  6502. +static void __init wndr3700_setup(void)
  6503. +{
  6504. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  6505. +
  6506. + ar71xx_set_mac_base(art);
  6507. +
  6508. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  6509. + ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6510. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6511. + ar71xx_eth0_data.speed = SPEED_1000;
  6512. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6513. +
  6514. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  6515. + ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6516. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6517. + ar71xx_eth1_data.phy_mask = 0x10;
  6518. +
  6519. + ar71xx_add_device_eth(0);
  6520. + ar71xx_add_device_eth(1);
  6521. +
  6522. + ar71xx_add_device_usb();
  6523. +
  6524. + ar71xx_add_device_m25p80(&wndr3700_flash_data);
  6525. +
  6526. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio),
  6527. + wndr3700_leds_gpio);
  6528. +
  6529. + ar71xx_add_device_gpio_buttons(-1, WNDR3700_BUTTONS_POLL_INTERVAL,
  6530. + ARRAY_SIZE(wndr3700_gpio_buttons),
  6531. + wndr3700_gpio_buttons);
  6532. +
  6533. + platform_device_register(&wndr3700_rtl8366s_device);
  6534. + platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0);
  6535. +
  6536. + ap94_pci_enable_quirk_wndr3700();
  6537. + ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET,
  6538. + art + WNDR3700_WMAC0_MAC_OFFSET,
  6539. + art + WNDR3700_CALDATA1_OFFSET,
  6540. + art + WNDR3700_WMAC1_MAC_OFFSET);
  6541. +}
  6542. +
  6543. +MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700",
  6544. + wndr3700_setup);
  6545. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.36/arch/mips/ar71xx/mach-wnr2000.c
  6546. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100
  6547. +++ linux-2.6.36/arch/mips/ar71xx/mach-wnr2000.c 2010-12-17 18:34:51.000000000 +0100
  6548. @@ -0,0 +1,148 @@
  6549. +/*
  6550. + * NETGEAR WNR2000 board support
  6551. + *
  6552. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6553. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6554. + * Copyright (C) 2008-2009 Andy Boyett <agb@openwrt.org>
  6555. + *
  6556. + * This program is free software; you can redistribute it and/or modify it
  6557. + * under the terms of the GNU General Public License version 2 as published
  6558. + * by the Free Software Foundation.
  6559. + */
  6560. +
  6561. +#include <linux/mtd/mtd.h>
  6562. +#include <linux/mtd/partitions.h>
  6563. +
  6564. +#include <asm/mach-ar71xx/ar71xx.h>
  6565. +
  6566. +#include "machtype.h"
  6567. +#include "devices.h"
  6568. +#include "dev-m25p80.h"
  6569. +#include "dev-ar913x-wmac.h"
  6570. +#include "dev-gpio-buttons.h"
  6571. +#include "dev-leds-gpio.h"
  6572. +
  6573. +#define WNR2000_GPIO_LED_PWR_GREEN 14
  6574. +#define WNR2000_GPIO_LED_PWR_AMBER 7
  6575. +#define WNR2000_GPIO_LED_WPS 4
  6576. +#define WNR2000_GPIO_LED_WLAN 6
  6577. +#define WNR2000_GPIO_BTN_RESET 21
  6578. +#define WNR2000_GPIO_BTN_WPS 8
  6579. +
  6580. +#define WNR2000_BUTTONS_POLL_INTERVAL 20
  6581. +
  6582. +#ifdef CONFIG_MTD_PARTITIONS
  6583. +static struct mtd_partition wnr2000_partitions[] = {
  6584. + {
  6585. + .name = "u-boot",
  6586. + .offset = 0,
  6587. + .size = 0x040000,
  6588. + .mask_flags = MTD_WRITEABLE,
  6589. + } , {
  6590. + .name = "u-boot-env",
  6591. + .offset = 0x040000,
  6592. + .size = 0x010000,
  6593. + } , {
  6594. + .name = "rootfs",
  6595. + .offset = 0x050000,
  6596. + .size = 0x240000,
  6597. + } , {
  6598. + .name = "user-config",
  6599. + .offset = 0x290000,
  6600. + .size = 0x010000,
  6601. + } , {
  6602. + .name = "uImage",
  6603. + .offset = 0x2a0000,
  6604. + .size = 0x120000,
  6605. + } , {
  6606. + .name = "language_table",
  6607. + .offset = 0x3c0000,
  6608. + .size = 0x020000,
  6609. + } , {
  6610. + .name = "rootfs_checksum",
  6611. + .offset = 0x3e0000,
  6612. + .size = 0x010000,
  6613. + } , {
  6614. + .name = "art",
  6615. + .offset = 0x3f0000,
  6616. + .size = 0x010000,
  6617. + .mask_flags = MTD_WRITEABLE,
  6618. + }
  6619. +};
  6620. +#endif /* CONFIG_MTD_PARTITIONS */
  6621. +
  6622. +static struct flash_platform_data wnr2000_flash_data = {
  6623. +#ifdef CONFIG_MTD_PARTITIONS
  6624. + .parts = wnr2000_partitions,
  6625. + .nr_parts = ARRAY_SIZE(wnr2000_partitions),
  6626. +#endif
  6627. +};
  6628. +
  6629. +static struct gpio_led wnr2000_leds_gpio[] __initdata = {
  6630. + {
  6631. + .name = "wnr2000:green:power",
  6632. + .gpio = WNR2000_GPIO_LED_PWR_GREEN,
  6633. + .active_low = 1,
  6634. + }, {
  6635. + .name = "wnr2000:amber:power",
  6636. + .gpio = WNR2000_GPIO_LED_PWR_AMBER,
  6637. + .active_low = 1,
  6638. + }, {
  6639. + .name = "wnr2000:green:wps",
  6640. + .gpio = WNR2000_GPIO_LED_WPS,
  6641. + .active_low = 1,
  6642. + }, {
  6643. + .name = "wnr2000:blue:wlan",
  6644. + .gpio = WNR2000_GPIO_LED_WLAN,
  6645. + .active_low = 1,
  6646. + }
  6647. +};
  6648. +
  6649. +static struct gpio_button wnr2000_gpio_buttons[] __initdata = {
  6650. + {
  6651. + .desc = "reset",
  6652. + .type = EV_KEY,
  6653. + .code = KEY_RESTART,
  6654. + .threshold = 3,
  6655. + .gpio = WNR2000_GPIO_BTN_RESET,
  6656. + }, {
  6657. + .desc = "wps",
  6658. + .type = EV_KEY,
  6659. + .code = KEY_WPS_BUTTON,
  6660. + .threshold = 3,
  6661. + .gpio = WNR2000_GPIO_BTN_WPS,
  6662. + }
  6663. +};
  6664. +
  6665. +static void __init wnr2000_setup(void)
  6666. +{
  6667. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6668. +
  6669. + ar71xx_set_mac_base(eeprom);
  6670. + ar71xx_add_device_mdio(0x0);
  6671. +
  6672. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6673. + ar71xx_eth0_data.speed = SPEED_100;
  6674. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6675. + ar71xx_eth0_data.has_ar8216 = 1;
  6676. +
  6677. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6678. + ar71xx_eth1_data.phy_mask = 0x10;
  6679. +
  6680. + ar71xx_add_device_eth(0);
  6681. + ar71xx_add_device_eth(1);
  6682. +
  6683. + ar71xx_add_device_m25p80(&wnr2000_flash_data);
  6684. +
  6685. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio),
  6686. + wnr2000_leds_gpio);
  6687. +
  6688. + ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL,
  6689. + ARRAY_SIZE(wnr2000_gpio_buttons),
  6690. + wnr2000_gpio_buttons);
  6691. +
  6692. +
  6693. + ar913x_add_device_wmac(eeprom, NULL);
  6694. +}
  6695. +
  6696. +MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup);
  6697. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.36/arch/mips/ar71xx/mach-wp543.c
  6698. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100
  6699. +++ linux-2.6.36/arch/mips/ar71xx/mach-wp543.c 2010-12-17 18:34:51.000000000 +0100
  6700. @@ -0,0 +1,99 @@
  6701. +/*
  6702. + * Compex WP543/WPJ543 board support
  6703. + *
  6704. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6705. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6706. + *
  6707. + * This program is free software; you can redistribute it and/or modify it
  6708. + * under the terms of the GNU General Public License version 2 as published
  6709. + * by the Free Software Foundation.
  6710. + */
  6711. +
  6712. +#include <linux/mtd/mtd.h>
  6713. +#include <linux/mtd/partitions.h>
  6714. +
  6715. +#include <asm/mach-ar71xx/ar71xx.h>
  6716. +
  6717. +#include "machtype.h"
  6718. +#include "devices.h"
  6719. +#include "dev-m25p80.h"
  6720. +#include "dev-pb42-pci.h"
  6721. +#include "dev-gpio-buttons.h"
  6722. +#include "dev-leds-gpio.h"
  6723. +#include "dev-usb.h"
  6724. +
  6725. +#define WP543_GPIO_SW6 2
  6726. +#define WP543_GPIO_LED_1 3
  6727. +#define WP543_GPIO_LED_2 4
  6728. +#define WP543_GPIO_LED_WLAN 5
  6729. +#define WP543_GPIO_LED_CONN 6
  6730. +#define WP543_GPIO_LED_DIAG 7
  6731. +#define WP543_GPIO_SW4 8
  6732. +
  6733. +#define WP543_BUTTONS_POLL_INTERVAL 20
  6734. +
  6735. +static struct gpio_led wp543_leds_gpio[] __initdata = {
  6736. + {
  6737. + .name = "wp543:green:led1",
  6738. + .gpio = WP543_GPIO_LED_1,
  6739. + .active_low = 1,
  6740. + }, {
  6741. + .name = "wp543:green:led2",
  6742. + .gpio = WP543_GPIO_LED_2,
  6743. + .active_low = 1,
  6744. + }, {
  6745. + .name = "wp543:green:wlan",
  6746. + .gpio = WP543_GPIO_LED_WLAN,
  6747. + .active_low = 1,
  6748. + }, {
  6749. + .name = "wp543:green:conn",
  6750. + .gpio = WP543_GPIO_LED_CONN,
  6751. + .active_low = 1,
  6752. + }, {
  6753. + .name = "wp543:green:diag",
  6754. + .gpio = WP543_GPIO_LED_DIAG,
  6755. + .active_low = 1,
  6756. + }
  6757. +};
  6758. +
  6759. +static struct gpio_button wp543_gpio_buttons[] __initdata = {
  6760. + {
  6761. + .desc = "sw6",
  6762. + .type = EV_KEY,
  6763. + .code = BTN_0,
  6764. + .threshold = 3,
  6765. + .gpio = WP543_GPIO_SW6,
  6766. + }, {
  6767. + .desc = "sw4",
  6768. + .type = EV_KEY,
  6769. + .code = BTN_1,
  6770. + .threshold = 3,
  6771. + .gpio = WP543_GPIO_SW4,
  6772. + }
  6773. +};
  6774. +
  6775. +static void __init wp543_setup(void)
  6776. +{
  6777. + ar71xx_add_device_m25p80(NULL);
  6778. +
  6779. + ar71xx_add_device_mdio(0xfffffff7);
  6780. +
  6781. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6782. + ar71xx_eth0_data.phy_mask = 0x08;
  6783. + ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC |
  6784. + RESET_MODULE_GE0_PHY;
  6785. + ar71xx_add_device_eth(0);
  6786. +
  6787. + ar71xx_add_device_usb();
  6788. +
  6789. + pb42_pci_init();
  6790. +
  6791. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio),
  6792. + wp543_leds_gpio);
  6793. +
  6794. + ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL,
  6795. + ARRAY_SIZE(wp543_gpio_buttons),
  6796. + wp543_gpio_buttons);
  6797. +}
  6798. +
  6799. +MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup);
  6800. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.36/arch/mips/ar71xx/mach-wrt160nl.c
  6801. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100
  6802. +++ linux-2.6.36/arch/mips/ar71xx/mach-wrt160nl.c 2010-12-17 18:34:51.000000000 +0100
  6803. @@ -0,0 +1,158 @@
  6804. +/*
  6805. + * Linksys WRT160NL board support
  6806. + *
  6807. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  6808. + *
  6809. + * This program is free software; you can redistribute it and/or modify it
  6810. + * under the terms of the GNU General Public License version 2 as published
  6811. + * by the Free Software Foundation.
  6812. + */
  6813. +
  6814. +#include <linux/mtd/mtd.h>
  6815. +#include <linux/mtd/partitions.h>
  6816. +
  6817. +#include <asm/mach-ar71xx/ar71xx.h>
  6818. +
  6819. +#include "machtype.h"
  6820. +#include "devices.h"
  6821. +#include "dev-m25p80.h"
  6822. +#include "dev-ar913x-wmac.h"
  6823. +#include "dev-gpio-buttons.h"
  6824. +#include "dev-leds-gpio.h"
  6825. +#include "dev-usb.h"
  6826. +#include "nvram.h"
  6827. +
  6828. +#define WRT160NL_GPIO_LED_POWER 14
  6829. +#define WRT160NL_GPIO_LED_WPS_AMBER 9
  6830. +#define WRT160NL_GPIO_LED_WPS_BLUE 8
  6831. +#define WRT160NL_GPIO_LED_WLAN 6
  6832. +
  6833. +#define WRT160NL_GPIO_BTN_WPS 7
  6834. +#define WRT160NL_GPIO_BTN_RESET 21
  6835. +
  6836. +#define WRT160NL_BUTTONS_POLL_INTERVAL 20
  6837. +
  6838. +#define WRT160NL_NVRAM_ADDR 0x1f7e0000
  6839. +#define WRT160NL_NVRAM_SIZE 0x10000
  6840. +
  6841. +#ifdef CONFIG_MTD_PARTITIONS
  6842. +static struct mtd_partition wrt160nl_partitions[] = {
  6843. + {
  6844. + .name = "u-boot",
  6845. + .offset = 0,
  6846. + .size = 0x040000,
  6847. + .mask_flags = MTD_WRITEABLE,
  6848. + } , {
  6849. + .name = "kernel",
  6850. + .offset = 0x040000,
  6851. + .size = 0x0e0000,
  6852. + } , {
  6853. + .name = "filesytem",
  6854. + .offset = 0x120000,
  6855. + .size = 0x6c0000,
  6856. + } , {
  6857. + .name = "nvram",
  6858. + .offset = 0x7e0000,
  6859. + .size = 0x010000,
  6860. + .mask_flags = MTD_WRITEABLE,
  6861. + } , {
  6862. + .name = "ART",
  6863. + .offset = 0x7f0000,
  6864. + .size = 0x010000,
  6865. + .mask_flags = MTD_WRITEABLE,
  6866. + } , {
  6867. + .name = "firmware",
  6868. + .offset = 0x040000,
  6869. + .size = 0x7a0000,
  6870. + }
  6871. +};
  6872. +#endif /* CONFIG_MTD_PARTITIONS */
  6873. +
  6874. +static struct flash_platform_data wrt160nl_flash_data = {
  6875. +#ifdef CONFIG_MTD_PARTITIONS
  6876. + .parts = wrt160nl_partitions,
  6877. + .nr_parts = ARRAY_SIZE(wrt160nl_partitions),
  6878. +#endif
  6879. +};
  6880. +
  6881. +static struct gpio_led wrt160nl_leds_gpio[] __initdata = {
  6882. + {
  6883. + .name = "wrt160nl:blue:power",
  6884. + .gpio = WRT160NL_GPIO_LED_POWER,
  6885. + .active_low = 1,
  6886. + .default_trigger = "default-on",
  6887. + }, {
  6888. + .name = "wrt160nl:amber:wps",
  6889. + .gpio = WRT160NL_GPIO_LED_WPS_AMBER,
  6890. + .active_low = 1,
  6891. + }, {
  6892. + .name = "wrt160nl:blue:wps",
  6893. + .gpio = WRT160NL_GPIO_LED_WPS_BLUE,
  6894. + .active_low = 1,
  6895. + }, {
  6896. + .name = "wrt160nl:blue:wlan",
  6897. + .gpio = WRT160NL_GPIO_LED_WLAN,
  6898. + .active_low = 1,
  6899. + }
  6900. +};
  6901. +
  6902. +static struct gpio_button wrt160nl_gpio_buttons[] __initdata = {
  6903. + {
  6904. + .desc = "reset",
  6905. + .type = EV_KEY,
  6906. + .code = KEY_RESTART,
  6907. + .threshold = 3,
  6908. + .gpio = WRT160NL_GPIO_BTN_RESET,
  6909. + .active_low = 1,
  6910. + }, {
  6911. + .desc = "wps",
  6912. + .type = EV_KEY,
  6913. + .code = KEY_WPS_BUTTON,
  6914. + .threshold = 3,
  6915. + .gpio = WRT160NL_GPIO_BTN_WPS,
  6916. + .active_low = 1,
  6917. + }
  6918. +};
  6919. +
  6920. +static void __init wrt160nl_setup(void)
  6921. +{
  6922. + const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR);
  6923. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6924. + u8 mac[6];
  6925. +
  6926. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6927. + "lan_hwaddr=", mac) == 0)
  6928. + ar71xx_set_mac_base(mac);
  6929. +
  6930. + ar71xx_add_device_mdio(0x0);
  6931. +
  6932. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6933. + ar71xx_eth0_data.phy_mask = 0x01;
  6934. +
  6935. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6936. + ar71xx_eth1_data.phy_mask = 0x10;
  6937. +
  6938. + ar71xx_add_device_eth(0);
  6939. + ar71xx_add_device_eth(1);
  6940. +
  6941. + ar71xx_add_device_m25p80(&wrt160nl_flash_data);
  6942. +
  6943. + ar71xx_add_device_usb();
  6944. +
  6945. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6946. + "wl0_hwaddr=", mac) == 0)
  6947. + ar913x_add_device_wmac(eeprom, mac);
  6948. + else
  6949. + ar913x_add_device_wmac(eeprom, NULL);
  6950. +
  6951. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio),
  6952. + wrt160nl_leds_gpio);
  6953. +
  6954. + ar71xx_add_device_gpio_buttons(-1, WRT160NL_BUTTONS_POLL_INTERVAL,
  6955. + ARRAY_SIZE(wrt160nl_gpio_buttons),
  6956. + wrt160nl_gpio_buttons);
  6957. +
  6958. +}
  6959. +
  6960. +MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL",
  6961. + wrt160nl_setup);
  6962. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.36/arch/mips/ar71xx/mach-wrt400n.c
  6963. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100
  6964. +++ linux-2.6.36/arch/mips/ar71xx/mach-wrt400n.c 2010-12-17 18:34:51.000000000 +0100
  6965. @@ -0,0 +1,168 @@
  6966. +/*
  6967. + * Linksys WRT400N board support
  6968. + *
  6969. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6970. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  6971. + *
  6972. + * This program is free software; you can redistribute it and/or modify it
  6973. + * under the terms of the GNU General Public License version 2 as published
  6974. + * by the Free Software Foundation.
  6975. + */
  6976. +
  6977. +#include <linux/mtd/mtd.h>
  6978. +#include <linux/mtd/partitions.h>
  6979. +
  6980. +#include <asm/mach-ar71xx/ar71xx.h>
  6981. +
  6982. +#include "machtype.h"
  6983. +#include "devices.h"
  6984. +#include "dev-ap94-pci.h"
  6985. +#include "dev-m25p80.h"
  6986. +#include "dev-gpio-buttons.h"
  6987. +#include "dev-leds-gpio.h"
  6988. +
  6989. +#define WRT400N_GPIO_LED_ORANGE 5
  6990. +#define WRT400N_GPIO_LED_GREEN 4
  6991. +#define WRT400N_GPIO_LED_POWER 1
  6992. +#define WRT400N_GPIO_LED_WLAN 0
  6993. +
  6994. +#define WRT400N_GPIO_BTN_RESET 8
  6995. +#define WRT400N_GPIO_BTN_WLSEC 3
  6996. +
  6997. +#define WRT400N_BUTTONS_POLL_INTERVAL 20
  6998. +
  6999. +#define WRT400N_MAC_ADDR_OFFSET 0x120c
  7000. +#define WRT400N_CALDATA0_OFFSET 0x1000
  7001. +#define WRT400N_CALDATA1_OFFSET 0x5000
  7002. +
  7003. +#ifdef CONFIG_MTD_PARTITIONS
  7004. +static struct mtd_partition wrt400n_partitions[] = {
  7005. + {
  7006. + .name = "uboot",
  7007. + .offset = 0,
  7008. + .size = 0x030000,
  7009. + .mask_flags = MTD_WRITEABLE,
  7010. + } , {
  7011. + .name = "env",
  7012. + .offset = 0x030000,
  7013. + .size = 0x010000,
  7014. + .mask_flags = MTD_WRITEABLE,
  7015. + } , {
  7016. + .name = "linux",
  7017. + .offset = 0x040000,
  7018. + .size = 0x140000,
  7019. + } , {
  7020. + .name = "rootfs",
  7021. + .offset = 0x180000,
  7022. + .size = 0x630000,
  7023. + } , {
  7024. + .name = "nvram",
  7025. + .offset = 0x7b0000,
  7026. + .size = 0x010000,
  7027. + .mask_flags = MTD_WRITEABLE,
  7028. + } , {
  7029. + .name = "factory",
  7030. + .offset = 0x7c0000,
  7031. + .size = 0x010000,
  7032. + .mask_flags = MTD_WRITEABLE,
  7033. + } , {
  7034. + .name = "language",
  7035. + .offset = 0x7d0000,
  7036. + .size = 0x020000,
  7037. + .mask_flags = MTD_WRITEABLE,
  7038. + } , {
  7039. + .name = "caldata",
  7040. + .offset = 0x7f0000,
  7041. + .size = 0x010000,
  7042. + .mask_flags = MTD_WRITEABLE,
  7043. + } , {
  7044. + .name = "firmware",
  7045. + .offset = 0x040000,
  7046. + .size = 0x770000,
  7047. + }
  7048. +};
  7049. +#endif /* CONFIG_MTD_PARTITIONS */
  7050. +
  7051. +static struct flash_platform_data wrt400n_flash_data = {
  7052. +#ifdef CONFIG_MTD_PARTITIONS
  7053. + .parts = wrt400n_partitions,
  7054. + .nr_parts = ARRAY_SIZE(wrt400n_partitions),
  7055. +#endif
  7056. +};
  7057. +
  7058. +static struct gpio_led wrt400n_leds_gpio[] __initdata = {
  7059. + {
  7060. + .name = "wrt400n:green:status",
  7061. + .gpio = WRT400N_GPIO_LED_GREEN,
  7062. + .active_low = 1,
  7063. + }, {
  7064. + .name = "wrt400n:amber:aoss",
  7065. + .gpio = WRT400N_GPIO_LED_ORANGE,
  7066. + .active_low = 1,
  7067. + }, {
  7068. + .name = "wrt400n:green:wlan",
  7069. + .gpio = WRT400N_GPIO_LED_WLAN,
  7070. + .active_low = 1,
  7071. + }, {
  7072. + .name = "wrt400n:green:power",
  7073. + .gpio = WRT400N_GPIO_LED_POWER,
  7074. + .active_low = 1,
  7075. + }
  7076. +};
  7077. +
  7078. +static struct gpio_button wrt400n_gpio_buttons[] __initdata = {
  7079. + {
  7080. + .desc = "reset",
  7081. + .type = EV_KEY,
  7082. + .code = KEY_RESTART,
  7083. + .threshold = 3,
  7084. + .gpio = WRT400N_GPIO_BTN_RESET,
  7085. + .active_low = 1,
  7086. + } , {
  7087. + .desc = "wlsec",
  7088. + .type = EV_KEY,
  7089. + .code = KEY_WPS_BUTTON,
  7090. + .threshold = 3,
  7091. + .gpio = WRT400N_GPIO_BTN_WLSEC,
  7092. + .active_low = 1,
  7093. + }
  7094. +};
  7095. +
  7096. +static void __init wrt400n_setup(void)
  7097. +{
  7098. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  7099. + u8 mac[6];
  7100. + int i;
  7101. +
  7102. + memcpy(mac, art + WRT400N_MAC_ADDR_OFFSET, 6);
  7103. + for (i = 5; i >= 3; i--)
  7104. + if (++mac[i] != 0x00) break;
  7105. +
  7106. + ar71xx_set_mac_base(mac);
  7107. +
  7108. + ar71xx_add_device_mdio(0x0);
  7109. +
  7110. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7111. + ar71xx_eth0_data.speed = SPEED_100;
  7112. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7113. +
  7114. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7115. + ar71xx_eth1_data.phy_mask = 0x10;
  7116. +
  7117. + ar71xx_add_device_eth(0);
  7118. + ar71xx_add_device_eth(1);
  7119. +
  7120. + ar71xx_add_device_m25p80(&wrt400n_flash_data);
  7121. +
  7122. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio),
  7123. + wrt400n_leds_gpio);
  7124. +
  7125. + ar71xx_add_device_gpio_buttons(-1, WRT400N_BUTTONS_POLL_INTERVAL,
  7126. + ARRAY_SIZE(wrt400n_gpio_buttons),
  7127. + wrt400n_gpio_buttons);
  7128. +
  7129. + ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL,
  7130. + art + WRT400N_CALDATA1_OFFSET, NULL);
  7131. +}
  7132. +
  7133. +MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup);
  7134. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.36/arch/mips/ar71xx/mach-wzr-hp-g300nh.c
  7135. --- linux-2.6.36.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100
  7136. +++ linux-2.6.36/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2010-12-17 18:34:51.000000000 +0100
  7137. @@ -0,0 +1,265 @@
  7138. +/*
  7139. + * Buffalo WZR-HP-G300NH board support
  7140. + *
  7141. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  7142. + *
  7143. + * This program is free software; you can redistribute it and/or modify it
  7144. + * under the terms of the GNU General Public License version 2 as published
  7145. + * by the Free Software Foundation.
  7146. + */
  7147. +
  7148. +#include <linux/platform_device.h>
  7149. +#include <linux/mtd/mtd.h>
  7150. +#include <linux/mtd/partitions.h>
  7151. +#include <linux/nxp_74hc153.h>
  7152. +#include <linux/rtl8366s.h>
  7153. +
  7154. +#include <asm/mips_machine.h>
  7155. +#include <asm/mach-ar71xx/ar71xx.h>
  7156. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  7157. +
  7158. +#include "machtype.h"
  7159. +#include "devices.h"
  7160. +#include "dev-ar913x-wmac.h"
  7161. +#include "dev-gpio-buttons.h"
  7162. +#include "dev-leds-gpio.h"
  7163. +#include "dev-usb.h"
  7164. +
  7165. +#define WZRHPG300NH_GPIO_LED_USB 0
  7166. +#define WZRHPG300NH_GPIO_LED_DIAG 1
  7167. +#define WZRHPG300NH_GPIO_LED_WIRELESS 6
  7168. +#define WZRHPG300NH_GPIO_LED_SECURITY 17
  7169. +#define WZRHPG300NH_GPIO_LED_ROUTER 18
  7170. +
  7171. +#define WZRHPG300NH_GPIO_RTL8366_SDA 19
  7172. +#define WZRHPG300NH_GPIO_RTL8366_SCK 20
  7173. +
  7174. +#define WZRHPG300NH_GPIO_74HC153_S0 9
  7175. +#define WZRHPG300NH_GPIO_74HC153_S1 11
  7176. +#define WZRHPG300NH_GPIO_74HC153_1Y 12
  7177. +#define WZRHPG300NH_GPIO_74HC153_2Y 14
  7178. +
  7179. +#define WZRHPG300NH_GPIO_EXP_BASE 32
  7180. +#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0)
  7181. +#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1)
  7182. +#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2)
  7183. +#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3)
  7184. +#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5)
  7185. +#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6)
  7186. +#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7)
  7187. +
  7188. +#define WZRHPG300NH_BUTTONS_POLL_INTERVAL 20
  7189. +
  7190. +#define WZRHPG300NH_MAC_OFFSET 0x20c
  7191. +
  7192. +#ifdef CONFIG_MTD_PARTITIONS
  7193. +static struct mtd_partition wzrhpg300nh_flash_partitions[] = {
  7194. + {
  7195. + .name = "u-boot",
  7196. + .offset = 0,
  7197. + .size = 0x0040000,
  7198. + .mask_flags = MTD_WRITEABLE,
  7199. + }, {
  7200. + .name = "u-boot-env",
  7201. + .offset = 0x0040000,
  7202. + .size = 0x0020000,
  7203. + .mask_flags = MTD_WRITEABLE,
  7204. + }, {
  7205. + .name = "kernel",
  7206. + .offset = 0x0060000,
  7207. + .size = 0x0100000,
  7208. + }, {
  7209. + .name = "rootfs",
  7210. + .offset = 0x0160000,
  7211. + .size = 0x1e60000,
  7212. + }, {
  7213. + .name = "user_property",
  7214. + .offset = 0x1fc0000,
  7215. + .size = 0x0020000,
  7216. + .mask_flags = MTD_WRITEABLE,
  7217. + }, {
  7218. + .name = "art",
  7219. + .offset = 0x1fe0000,
  7220. + .size = 0x0020000,
  7221. + .mask_flags = MTD_WRITEABLE,
  7222. + }, {
  7223. + .name = "firmware",
  7224. + .offset = 0x0060000,
  7225. + .size = 0x1f60000,
  7226. + }
  7227. +};
  7228. +#endif /* CONFIG_MTD_PARTITIONS */
  7229. +
  7230. +static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = {
  7231. + .width = 2,
  7232. +#ifdef CONFIG_MTD_PARTITIONS
  7233. + .parts = wzrhpg300nh_flash_partitions,
  7234. + .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions),
  7235. +#endif
  7236. +};
  7237. +
  7238. +#define WZRHPG300NH_FLASH_BASE 0x1e000000
  7239. +#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024)
  7240. +
  7241. +static struct resource wzrhpg300nh_flash_resources[] = {
  7242. + [0] = {
  7243. + .start = WZRHPG300NH_FLASH_BASE,
  7244. + .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1,
  7245. + .flags = IORESOURCE_MEM,
  7246. + },
  7247. +};
  7248. +
  7249. +static struct platform_device wzrhpg300nh_flash_device = {
  7250. + .name = "ar91xx-flash",
  7251. + .id = -1,
  7252. + .resource = wzrhpg300nh_flash_resources,
  7253. + .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources),
  7254. + .dev = {
  7255. + .platform_data = &wzrhpg300nh_flash_data,
  7256. + }
  7257. +};
  7258. +
  7259. +static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = {
  7260. + {
  7261. + .name = "wzr-hp-g300nh:orange:security",
  7262. + .gpio = WZRHPG300NH_GPIO_LED_SECURITY,
  7263. + .active_low = 1,
  7264. + }, {
  7265. + .name = "wzr-hp-g300nh:green:wireless",
  7266. + .gpio = WZRHPG300NH_GPIO_LED_WIRELESS,
  7267. + .active_low = 1,
  7268. + }, {
  7269. + .name = "wzr-hp-g300nh:green:router",
  7270. + .gpio = WZRHPG300NH_GPIO_LED_ROUTER,
  7271. + .active_low = 1,
  7272. + }, {
  7273. + .name = "wzr-hp-g300nh:red:diag",
  7274. + .gpio = WZRHPG300NH_GPIO_LED_DIAG,
  7275. + .active_low = 1,
  7276. + }, {
  7277. + .name = "wzr-hp-g300nh:blue:usb",
  7278. + .gpio = WZRHPG300NH_GPIO_LED_USB,
  7279. + .active_low = 1,
  7280. + }
  7281. +};
  7282. +
  7283. +static struct gpio_button wzrhpg300nh_gpio_buttons[] __initdata = {
  7284. + {
  7285. + .desc = "reset",
  7286. + .type = EV_KEY,
  7287. + .code = KEY_RESTART,
  7288. + .threshold = 3,
  7289. + .gpio = WZRHPG300NH_GPIO_BTN_RESET,
  7290. + .active_low = 1,
  7291. + }, {
  7292. + .desc = "aoss",
  7293. + .type = EV_KEY,
  7294. + .code = KEY_WPS_BUTTON,
  7295. + .threshold = 3,
  7296. + .gpio = WZRHPG300NH_GPIO_BTN_AOSS,
  7297. + .active_low = 1,
  7298. + }, {
  7299. + .desc = "usb",
  7300. + .type = EV_KEY,
  7301. + .code = BTN_2,
  7302. + .threshold = 3,
  7303. + .gpio = WZRHPG300NH_GPIO_BTN_USB,
  7304. + .active_low = 1,
  7305. + }, {
  7306. + .desc = "qos_on",
  7307. + .type = EV_KEY,
  7308. + .code = BTN_3,
  7309. + .threshold = 3,
  7310. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON,
  7311. + .active_low = 0,
  7312. + }, {
  7313. + .desc = "qos_off",
  7314. + .type = EV_KEY,
  7315. + .code = BTN_4,
  7316. + .threshold = 3,
  7317. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF,
  7318. + .active_low = 0,
  7319. + }, {
  7320. + .desc = "router_on",
  7321. + .type = EV_KEY,
  7322. + .code = BTN_5,
  7323. + .threshold = 3,
  7324. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON,
  7325. + .active_low = 0,
  7326. + }, {
  7327. + .desc = "router_auto",
  7328. + .type = EV_KEY,
  7329. + .code = BTN_6,
  7330. + .threshold = 3,
  7331. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO,
  7332. + .active_low = 0,
  7333. + }
  7334. +};
  7335. +
  7336. +static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = {
  7337. + .gpio_base = WZRHPG300NH_GPIO_EXP_BASE,
  7338. + .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0,
  7339. + .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1,
  7340. + .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y,
  7341. + .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y,
  7342. +};
  7343. +
  7344. +static struct platform_device wzrhpg300nh_74hc153_device = {
  7345. + .name = NXP_74HC153_DRIVER_NAME,
  7346. + .id = -1,
  7347. + .dev = {
  7348. + .platform_data = &wzrhpg300nh_74hc153_data,
  7349. + }
  7350. +};
  7351. +
  7352. +static struct rtl8366s_platform_data wzrhpg300nh_rtl8366s_data = {
  7353. + .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA,
  7354. + .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK,
  7355. +};
  7356. +
  7357. +static struct platform_device wzrhpg300nh_rtl8366s_device = {
  7358. + .name = RTL8366S_DRIVER_NAME,
  7359. + .id = -1,
  7360. + .dev = {
  7361. + .platform_data = &wzrhpg300nh_rtl8366s_data,
  7362. + }
  7363. +};
  7364. +
  7365. +static void __init wzrhpg300nh_setup(void)
  7366. +{
  7367. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7368. +
  7369. + ar71xx_set_mac_base(eeprom + WZRHPG300NH_MAC_OFFSET);
  7370. +
  7371. + ar71xx_eth0_pll_data.pll_1000 = 0x1e000100;
  7372. + ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7373. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7374. + ar71xx_eth0_data.speed = SPEED_1000;
  7375. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7376. +
  7377. + ar71xx_eth1_pll_data.pll_1000 = 0x1e000100;
  7378. + ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7379. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7380. + ar71xx_eth1_data.phy_mask = 0x10;
  7381. +
  7382. + ar71xx_add_device_eth(0);
  7383. + ar71xx_add_device_eth(1);
  7384. +
  7385. + ar71xx_add_device_usb();
  7386. + ar913x_add_device_wmac(eeprom, NULL);
  7387. +
  7388. + platform_device_register(&wzrhpg300nh_74hc153_device);
  7389. + platform_device_register(&wzrhpg300nh_flash_device);
  7390. + platform_device_register(&wzrhpg300nh_rtl8366s_device);
  7391. +
  7392. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio),
  7393. + wzrhpg300nh_leds_gpio);
  7394. +
  7395. + ar71xx_add_device_gpio_buttons(-1, WZRHPG300NH_BUTTONS_POLL_INTERVAL,
  7396. + ARRAY_SIZE(wzrhpg300nh_gpio_buttons),
  7397. + wzrhpg300nh_gpio_buttons);
  7398. +
  7399. +}
  7400. +
  7401. +MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH",
  7402. + "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup);
  7403. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/machtype.h linux-2.6.36/arch/mips/ar71xx/machtype.h
  7404. --- linux-2.6.36.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100
  7405. +++ linux-2.6.36/arch/mips/ar71xx/machtype.h 2010-12-17 18:34:51.000000000 +0100
  7406. @@ -0,0 +1,60 @@
  7407. +/*
  7408. + * Atheros AR71xx machine type definitions
  7409. + *
  7410. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  7411. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7412. + *
  7413. + * This program is free software; you can redistribute it and/or modify it
  7414. + * under the terms of the GNU General Public License version 2 as published
  7415. + * by the Free Software Foundation.
  7416. + */
  7417. +
  7418. +#ifndef _AR71XX_MACHTYPE_H
  7419. +#define _AR71XX_MACHTYPE_H
  7420. +
  7421. +#include <asm/mips_machine.h>
  7422. +
  7423. +enum ar71xx_mach_type {
  7424. + AR71XX_MACH_GENERIC = 0,
  7425. + AR71XX_MACH_AP81, /* Atheros AP81 */
  7426. + AR71XX_MACH_AP83, /* Atheros AP83 */
  7427. + AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */
  7428. + AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */
  7429. + AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */
  7430. + AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */
  7431. + AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */
  7432. + AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */
  7433. + AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */
  7434. + AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */
  7435. + AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */
  7436. + AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */
  7437. + AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */
  7438. + AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */
  7439. + AR71XX_MACH_PB42, /* Atheros PB42 */
  7440. + AR71XX_MACH_PB44, /* Atheros PB44 */
  7441. + AR71XX_MACH_PB92, /* Atheros PB92 */
  7442. + AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */
  7443. + AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */
  7444. + AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */
  7445. + AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */
  7446. + AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */
  7447. + AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */
  7448. + AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */
  7449. + AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */
  7450. + AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */
  7451. + AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */
  7452. + AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */
  7453. + AR71XX_MACH_UBNT_AR71XX, /* Ubiquiti AR71xx-based board */
  7454. + AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
  7455. + AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */
  7456. + AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
  7457. + AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
  7458. + AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */
  7459. + AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */
  7460. + AR71XX_MACH_WP543, /* Compex WP543 */
  7461. + AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */
  7462. + AR71XX_MACH_WRT400N, /* Linksys WRT400N */
  7463. + AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */
  7464. +};
  7465. +
  7466. +#endif /* _AR71XX_MACHTYPE_H */
  7467. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/nvram.c linux-2.6.36/arch/mips/ar71xx/nvram.c
  7468. --- linux-2.6.36.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
  7469. +++ linux-2.6.36/arch/mips/ar71xx/nvram.c 2010-12-17 18:34:51.000000000 +0100
  7470. @@ -0,0 +1,75 @@
  7471. +/*
  7472. + * Atheros AR71xx minimal nvram support
  7473. + *
  7474. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7475. + *
  7476. + * This program is free software; you can redistribute it and/or modify it
  7477. + * under the terms of the GNU General Public License version 2 as published
  7478. + * by the Free Software Foundation.
  7479. + */
  7480. +
  7481. +#include <linux/kernel.h>
  7482. +#include <linux/vmalloc.h>
  7483. +#include <linux/errno.h>
  7484. +#include <linux/init.h>
  7485. +#include <linux/string.h>
  7486. +
  7487. +#include "nvram.h"
  7488. +
  7489. +char *nvram_find_var(const char *name, const char *buf, unsigned buf_len)
  7490. +{
  7491. + unsigned len = strlen(name);
  7492. + char *cur, *last;
  7493. +
  7494. + if (buf_len == 0 || len == 0)
  7495. + return NULL;
  7496. +
  7497. + if (buf_len < len)
  7498. + return NULL;
  7499. +
  7500. + if (len == 1)
  7501. + return memchr(buf, (int) *name, buf_len);
  7502. +
  7503. + last = (char *) buf + buf_len - len;
  7504. + for (cur = (char *) buf; cur <= last; cur++)
  7505. + if (cur[0] == name[0] && memcmp(cur, name, len) == 0)
  7506. + return cur + len;
  7507. +
  7508. + return NULL;
  7509. +}
  7510. +
  7511. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7512. + const char *name, char *mac)
  7513. +{
  7514. + char *buf;
  7515. + char *mac_str;
  7516. + int ret;
  7517. + int t;
  7518. +
  7519. + buf = vmalloc(nvram_len);
  7520. + if (!buf)
  7521. + return -ENOMEM;
  7522. +
  7523. + memcpy(buf, nvram, nvram_len);
  7524. + buf[nvram_len - 1] = '\0';
  7525. +
  7526. + mac_str = nvram_find_var(name, buf, nvram_len);
  7527. + if (!mac_str) {
  7528. + ret = -EINVAL;
  7529. + goto free;
  7530. + }
  7531. +
  7532. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  7533. + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
  7534. +
  7535. + if (t != 6) {
  7536. + ret = -EINVAL;
  7537. + goto free;
  7538. + }
  7539. +
  7540. + ret = 0;
  7541. +
  7542. + free:
  7543. + vfree(buf);
  7544. + return ret;
  7545. +}
  7546. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/nvram.h linux-2.6.36/arch/mips/ar71xx/nvram.h
  7547. --- linux-2.6.36.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100
  7548. +++ linux-2.6.36/arch/mips/ar71xx/nvram.h 2010-12-17 18:34:51.000000000 +0100
  7549. @@ -0,0 +1,19 @@
  7550. +/*
  7551. + * Atheros AR71xx minimal nvram support
  7552. + *
  7553. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7554. + *
  7555. + * This program is free software; you can redistribute it and/or modify it
  7556. + * under the terms of the GNU General Public License version 2 as published
  7557. + * by the Free Software Foundation.
  7558. + */
  7559. +
  7560. +#ifndef _AR71XX_NVRAM_H
  7561. +#define _AR71XX_NVRAM_H
  7562. +
  7563. +char *nvram_find_var(const char *name, const char *buf,
  7564. + unsigned buf_len) __init;
  7565. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7566. + const char *name, char *mac) __init;
  7567. +
  7568. +#endif /* _AR71XX_NVRAM_H */
  7569. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/pci.c linux-2.6.36/arch/mips/ar71xx/pci.c
  7570. --- linux-2.6.36.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100
  7571. +++ linux-2.6.36/arch/mips/ar71xx/pci.c 2010-12-17 18:34:51.000000000 +0100
  7572. @@ -0,0 +1,93 @@
  7573. +/*
  7574. + * Atheros AR71xx PCI setup code
  7575. + *
  7576. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7577. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7578. + *
  7579. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7580. + *
  7581. + * This program is free software; you can redistribute it and/or modify it
  7582. + * under the terms of the GNU General Public License version 2 as published
  7583. + * by the Free Software Foundation.
  7584. + */
  7585. +
  7586. +#include <linux/kernel.h>
  7587. +
  7588. +#include <asm/traps.h>
  7589. +
  7590. +#include <asm/mach-ar71xx/ar71xx.h>
  7591. +#include <asm/mach-ar71xx/pci.h>
  7592. +
  7593. +unsigned ar71xx_pci_nr_irqs __initdata;
  7594. +struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  7595. +
  7596. +int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  7597. +
  7598. +static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
  7599. +{
  7600. + int err = 0;
  7601. +
  7602. + err = ar71xx_pci_be_handler(is_fixup);
  7603. +
  7604. + return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  7605. +}
  7606. +
  7607. +int pcibios_plat_dev_init(struct pci_dev *dev)
  7608. +{
  7609. + if (ar71xx_pci_plat_dev_init)
  7610. + return ar71xx_pci_plat_dev_init(dev);
  7611. +
  7612. + return 0;
  7613. +}
  7614. +
  7615. +int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
  7616. +{
  7617. + int ret = 0;
  7618. +
  7619. + switch (ar71xx_soc) {
  7620. + case AR71XX_SOC_AR7130:
  7621. + case AR71XX_SOC_AR7141:
  7622. + case AR71XX_SOC_AR7161:
  7623. + ret = ar71xx_pcibios_map_irq(dev, slot, pin);
  7624. + break;
  7625. +
  7626. + case AR71XX_SOC_AR7240:
  7627. + case AR71XX_SOC_AR7241:
  7628. + case AR71XX_SOC_AR7242:
  7629. + ret = ar724x_pcibios_map_irq(dev, slot, pin);
  7630. + break;
  7631. +
  7632. + default:
  7633. + break;
  7634. + }
  7635. +
  7636. + return ret;
  7637. +}
  7638. +
  7639. +int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  7640. +{
  7641. + int ret = 0;
  7642. +
  7643. + switch (ar71xx_soc) {
  7644. + case AR71XX_SOC_AR7130:
  7645. + case AR71XX_SOC_AR7141:
  7646. + case AR71XX_SOC_AR7161:
  7647. + board_be_handler = ar71xx_be_handler;
  7648. + ret = ar71xx_pcibios_init();
  7649. + break;
  7650. +
  7651. + case AR71XX_SOC_AR7240:
  7652. + case AR71XX_SOC_AR7241:
  7653. + case AR71XX_SOC_AR7242:
  7654. + ret = ar724x_pcibios_init();
  7655. + break;
  7656. +
  7657. + default:
  7658. + return 0;
  7659. + }
  7660. +
  7661. + ar71xx_pci_nr_irqs = nr_irqs;
  7662. + ar71xx_pci_irq_map = map;
  7663. +
  7664. + return ret;
  7665. +}
  7666. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/prom.c linux-2.6.36/arch/mips/ar71xx/prom.c
  7667. --- linux-2.6.36.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100
  7668. +++ linux-2.6.36/arch/mips/ar71xx/prom.c 2010-12-17 18:34:51.000000000 +0100
  7669. @@ -0,0 +1,105 @@
  7670. +/*
  7671. + * Atheros AR71xx SoC specific prom routines
  7672. + *
  7673. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7674. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7675. + *
  7676. + * This program is free software; you can redistribute it and/or modify it
  7677. + * under the terms of the GNU General Public License version 2 as published
  7678. + * by the Free Software Foundation.
  7679. + */
  7680. +
  7681. +#include <linux/kernel.h>
  7682. +#include <linux/init.h>
  7683. +#include <linux/io.h>
  7684. +#include <linux/string.h>
  7685. +
  7686. +#include <asm/bootinfo.h>
  7687. +#include <asm/addrspace.h>
  7688. +
  7689. +#include <asm/mach-ar71xx/ar71xx.h>
  7690. +
  7691. +static inline int is_valid_ram_addr(void *addr)
  7692. +{
  7693. + if (((u32) addr > KSEG0) &&
  7694. + ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX)))
  7695. + return 1;
  7696. +
  7697. + if (((u32) addr > KSEG1) &&
  7698. + ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX)))
  7699. + return 1;
  7700. +
  7701. + return 0;
  7702. +}
  7703. +
  7704. +static void __init ar71xx_prom_append_cmdline(const char *name,
  7705. + const char *value)
  7706. +{
  7707. + char buf[COMMAND_LINE_SIZE];
  7708. +
  7709. + snprintf(buf, sizeof(buf), " %s=%s", name, value);
  7710. + strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline));
  7711. +}
  7712. +
  7713. +static void __init ar71xx_prom_find_env(char **envp, const char *name)
  7714. +{
  7715. + int len = strlen(name);
  7716. + char **p;
  7717. +
  7718. + if (!is_valid_ram_addr(envp))
  7719. + return;
  7720. +
  7721. + for (p = envp; is_valid_ram_addr(*p); p++) {
  7722. + if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') {
  7723. + ar71xx_prom_append_cmdline(name, *p + len + 1);
  7724. + break;
  7725. + }
  7726. +
  7727. + /* RedBoot env comes in pointer pairs - key, value */
  7728. + if (strncmp(name, *p, len) == 0 && (*p)[len] == 0)
  7729. + if (is_valid_ram_addr(*(++p))) {
  7730. + ar71xx_prom_append_cmdline(name, *p);
  7731. + break;
  7732. + }
  7733. + }
  7734. +}
  7735. +
  7736. +static int inline ar71xx_use__image_cmdline(void) { return 0; }
  7737. +
  7738. +static __init void ar71xx_prom_init_cmdline(int argc, char **argv)
  7739. +{
  7740. + int i;
  7741. +
  7742. + if (ar71xx_use__image_cmdline())
  7743. + return;
  7744. +
  7745. + if (!is_valid_ram_addr(argv))
  7746. + return;
  7747. +
  7748. + for (i = 0; i < argc; i++)
  7749. + if (is_valid_ram_addr(argv[i])) {
  7750. + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
  7751. + strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
  7752. + }
  7753. +}
  7754. +
  7755. +void __init prom_init(void)
  7756. +{
  7757. + char **envp;
  7758. +
  7759. + printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, "
  7760. + "fw_arg2=%08x, fw_arg3=%08x\n",
  7761. + (unsigned int)fw_arg0, (unsigned int)fw_arg1,
  7762. + (unsigned int)fw_arg2, (unsigned int)fw_arg3);
  7763. +
  7764. +
  7765. + ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
  7766. +
  7767. + envp = (char **)fw_arg2;
  7768. + ar71xx_prom_find_env(envp, "board");
  7769. +}
  7770. +
  7771. +void __init prom_free_prom_memory(void)
  7772. +{
  7773. + /* We do not have to prom memory to free */
  7774. +}
  7775. diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/setup.c linux-2.6.36/arch/mips/ar71xx/setup.c
  7776. --- linux-2.6.36.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100
  7777. +++ linux-2.6.36/arch/mips/ar71xx/setup.c 2010-12-17 18:34:51.000000000 +0100
  7778. @@ -0,0 +1,310 @@
  7779. +/*
  7780. + * Atheros AR71xx SoC specific setup
  7781. + *
  7782. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7783. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7784. + *
  7785. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7786. + *
  7787. + * This program is free software; you can redistribute it and/or modify it
  7788. + * under the terms of the GNU General Public License version 2 as published
  7789. + * by the Free Software Foundation.
  7790. + */
  7791. +
  7792. +#include <linux/kernel.h>
  7793. +#include <linux/init.h>
  7794. +#include <linux/bootmem.h>
  7795. +
  7796. +#include <asm/bootinfo.h>
  7797. +#include <asm/time.h> /* for mips_hpt_frequency */
  7798. +#include <asm/reboot.h> /* for _machine_{restart,halt} */
  7799. +#include <asm/mips_machine.h>
  7800. +
  7801. +#include <asm/mach-ar71xx/ar71xx.h>
  7802. +
  7803. +#include "machtype.h"
  7804. +#include "devices.h"
  7805. +
  7806. +#define AR71XX_SYS_TYPE_LEN 64
  7807. +#define AR71XX_BASE_FREQ 40000000
  7808. +#define AR91XX_BASE_FREQ 5000000
  7809. +#define AR724X_BASE_FREQ 5000000
  7810. +
  7811. +u32 ar71xx_cpu_freq;
  7812. +EXPORT_SYMBOL_GPL(ar71xx_cpu_freq);
  7813. +
  7814. +u32 ar71xx_ahb_freq;
  7815. +EXPORT_SYMBOL_GPL(ar71xx_ahb_freq);
  7816. +
  7817. +u32 ar71xx_ddr_freq;
  7818. +EXPORT_SYMBOL_GPL(ar71xx_ddr_freq);
  7819. +
  7820. +enum ar71xx_soc_type ar71xx_soc;
  7821. +EXPORT_SYMBOL_GPL(ar71xx_soc);
  7822. +
  7823. +static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];
  7824. +
  7825. +static void ar71xx_restart(char *command)
  7826. +{
  7827. + ar71xx_device_stop(RESET_MODULE_FULL_CHIP);
  7828. + for (;;)
  7829. + if (cpu_wait)
  7830. + cpu_wait();
  7831. +}
  7832. +
  7833. +static void ar71xx_halt(void)
  7834. +{
  7835. + while (1)
  7836. + cpu_wait();
  7837. +}
  7838. +
  7839. +static void __init ar71xx_detect_mem_size(void)
  7840. +{
  7841. + unsigned long size;
  7842. +
  7843. + for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX;
  7844. + size <<= 1 ) {
  7845. + if (!memcmp(ar71xx_detect_mem_size,
  7846. + ar71xx_detect_mem_size + size, 1024))
  7847. + break;
  7848. + }
  7849. +
  7850. + add_memory_region(0, size, BOOT_MEM_RAM);
  7851. +}
  7852. +
  7853. +static void __init ar71xx_detect_sys_type(void)
  7854. +{
  7855. + char *chip = "????";
  7856. + u32 id;
  7857. + u32 major;
  7858. + u32 minor;
  7859. + u32 rev = 0;
  7860. +
  7861. + id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID);
  7862. + major = id & REV_ID_MAJOR_MASK;
  7863. +
  7864. + switch (major) {
  7865. + case REV_ID_MAJOR_AR71XX:
  7866. + minor = id & AR71XX_REV_ID_MINOR_MASK;
  7867. + rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
  7868. + rev &= AR71XX_REV_ID_REVISION_MASK;
  7869. + switch (minor) {
  7870. + case AR71XX_REV_ID_MINOR_AR7130:
  7871. + ar71xx_soc = AR71XX_SOC_AR7130;
  7872. + chip = "7130";
  7873. + break;
  7874. +
  7875. + case AR71XX_REV_ID_MINOR_AR7141:
  7876. + ar71xx_soc = AR71XX_SOC_AR7141;
  7877. + chip = "7141";
  7878. + break;
  7879. +
  7880. + case AR71XX_REV_ID_MINOR_AR7161:
  7881. + ar71xx_soc = AR71XX_SOC_AR7161;
  7882. + chip = "7161";
  7883. + break;
  7884. + }
  7885. + break;
  7886. +
  7887. + case REV_ID_MAJOR_AR7240:
  7888. + ar71xx_soc = AR71XX_SOC_AR7240;
  7889. + chip = "7240";
  7890. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7891. + break;
  7892. +
  7893. + case REV_ID_MAJOR_AR7241:
  7894. + ar71xx_soc = AR71XX_SOC_AR7241;
  7895. + chip = "7241";
  7896. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7897. + break;
  7898. +
  7899. + case REV_ID_MAJOR_AR7242:
  7900. + ar71xx_soc = AR71XX_SOC_AR7242;
  7901. + chip = "7242";
  7902. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7903. + break;
  7904. +
  7905. + case REV_ID_MAJOR_AR913X:
  7906. + minor = id & AR91XX_REV_ID_MINOR_MASK;
  7907. + rev = id >> AR91XX_REV_ID_REVISION_SHIFT;
  7908. + rev &= AR91XX_REV_ID_REVISION_MASK;
  7909. + switch (minor) {
  7910. + case AR91XX_REV_ID_MINOR_AR9130:
  7911. + ar71xx_soc = AR71XX_SOC_AR9130;
  7912. + chip = "9130";
  7913. + break;
  7914. +
  7915. + case AR91XX_REV_ID_MINOR_AR9132:
  7916. + ar71xx_soc = AR71XX_SOC_AR9132;
  7917. + chip = "9132";
  7918. + break;
  7919. + }
  7920. + break;
  7921. +
  7922. + default:
  7923. + panic("ar71xx: unknown chip id:0x%08x\n", id);
  7924. + }
  7925. +
  7926. + sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev);
  7927. +}
  7928. +
  7929. +static void __init ar91xx_detect_sys_frequency(void)
  7930. +{
  7931. + u32 pll;
  7932. + u32 freq;
  7933. + u32 div;
  7934. +
  7935. + pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
  7936. +
  7937. + div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
  7938. + freq = div * AR91XX_BASE_FREQ;
  7939. +
  7940. + ar71xx_cpu_freq = freq;
  7941. +
  7942. + div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1;
  7943. + ar71xx_ddr_freq = freq / div;
  7944. +
  7945. + div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2;
  7946. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7947. +}
  7948. +
  7949. +static void __init ar71xx_detect_sys_frequency(void)
  7950. +{
  7951. + u32 pll;
  7952. + u32 freq;
  7953. + u32 div;
  7954. +
  7955. + pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
  7956. +
  7957. + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
  7958. + freq = div * AR71XX_BASE_FREQ;
  7959. +
  7960. + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
  7961. + ar71xx_cpu_freq = freq / div;
  7962. +
  7963. + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
  7964. + ar71xx_ddr_freq = freq / div;
  7965. +
  7966. + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
  7967. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7968. +}
  7969. +
  7970. +static void __init ar724x_detect_sys_frequency(void)
  7971. +{
  7972. + u32 pll;
  7973. + u32 freq;
  7974. + u32 div;
  7975. +
  7976. + pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
  7977. +
  7978. + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
  7979. + freq = div * AR724X_BASE_FREQ;
  7980. +
  7981. + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
  7982. + freq *= div;
  7983. +
  7984. + ar71xx_cpu_freq = freq;
  7985. +
  7986. + div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
  7987. + ar71xx_ddr_freq = freq / div;
  7988. +
  7989. + div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
  7990. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7991. +}
  7992. +
  7993. +static void __init detect_sys_frequency(void)
  7994. +{
  7995. + switch (ar71xx_soc) {
  7996. + case AR71XX_SOC_AR7130:
  7997. + case AR71XX_SOC_AR7141:
  7998. + case AR71XX_SOC_AR7161:
  7999. + ar71xx_detect_sys_frequency();
  8000. + break;
  8001. +
  8002. + case AR71XX_SOC_AR7240:
  8003. + case AR71XX_SOC_AR7241:
  8004. + case AR71XX_SOC_AR7242:
  8005. + ar724x_detect_sys_frequency();
  8006. + break;
  8007. +
  8008. + case AR71XX_SOC_AR9130:
  8009. + case AR71XX_SOC_AR9132:
  8010. + ar91xx_detect_sys_frequency();
  8011. + break;
  8012. +
  8013. + default:
  8014. + BUG();
  8015. + }
  8016. +}
  8017. +
  8018. +const char *get_system_type(void)
  8019. +{
  8020. + return ar71xx_sys_type;
  8021. +}
  8022. +
  8023. +unsigned int __cpuinit get_c0_compare_irq(void)
  8024. +{
  8025. + return CP0_LEGACY_COMPARE_IRQ;
  8026. +}
  8027. +
  8028. +void __init plat_mem_setup(void)
  8029. +{
  8030. + set_io_port_base(KSEG1);
  8031. +
  8032. + ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
  8033. + AR71XX_DDR_CTRL_SIZE);
  8034. +
  8035. + ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
  8036. + AR71XX_PLL_SIZE);
  8037. +
  8038. + ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
  8039. + AR71XX_RESET_SIZE);
  8040. +
  8041. + ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  8042. +
  8043. + ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE,
  8044. + AR71XX_USB_CTRL_SIZE);
  8045. +
  8046. + ar71xx_detect_mem_size();
  8047. + ar71xx_detect_sys_type();
  8048. + detect_sys_frequency();
  8049. +
  8050. + printk(KERN_INFO
  8051. + "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n",
  8052. + ar71xx_sys_type,
  8053. + ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000,
  8054. + ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000,
  8055. + ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000);
  8056. +
  8057. + _machine_restart = ar71xx_restart;
  8058. + _machine_halt = ar71xx_halt;
  8059. + pm_power_off = ar71xx_halt;
  8060. +}
  8061. +
  8062. +void __init plat_time_init(void)
  8063. +{
  8064. + mips_hpt_frequency = ar71xx_cpu_freq / 2;
  8065. +}
  8066. +
  8067. +__setup("board=", mips_machtype_setup);
  8068. +
  8069. +static int __init ar71xx_machine_setup(void)
  8070. +{
  8071. + ar71xx_gpio_init();
  8072. +
  8073. + ar71xx_add_device_uart();
  8074. + ar71xx_add_device_wdt();
  8075. +
  8076. + mips_machine_setup();
  8077. + return 0;
  8078. +}
  8079. +
  8080. +arch_initcall(ar71xx_machine_setup);
  8081. +
  8082. +static void __init ar71xx_generic_init(void)
  8083. +{
  8084. + /* Nothing to do */
  8085. +}
  8086. +
  8087. +MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board",
  8088. + ar71xx_generic_init);
  8089. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/ar71xx.h
  8090. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100
  8091. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2010-12-17 18:34:51.000000000 +0100
  8092. @@ -0,0 +1,514 @@
  8093. +/*
  8094. + * Atheros AR71xx SoC specific definitions
  8095. + *
  8096. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8097. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8098. + *
  8099. + * Parts of this file are based on Atheros' 2.6.15 BSP
  8100. + *
  8101. + * This program is free software; you can redistribute it and/or modify it
  8102. + * under the terms of the GNU General Public License version 2 as published
  8103. + * by the Free Software Foundation.
  8104. + */
  8105. +
  8106. +#ifndef __ASM_MACH_AR71XX_H
  8107. +#define __ASM_MACH_AR71XX_H
  8108. +
  8109. +#include <linux/types.h>
  8110. +#include <linux/init.h>
  8111. +#include <linux/io.h>
  8112. +#include <linux/bitops.h>
  8113. +
  8114. +#ifndef __ASSEMBLER__
  8115. +
  8116. +#define AR71XX_PCI_MEM_BASE 0x10000000
  8117. +#define AR71XX_PCI_MEM_SIZE 0x08000000
  8118. +#define AR71XX_APB_BASE 0x18000000
  8119. +#define AR71XX_GE0_BASE 0x19000000
  8120. +#define AR71XX_GE0_SIZE 0x01000000
  8121. +#define AR71XX_GE1_BASE 0x1a000000
  8122. +#define AR71XX_GE1_SIZE 0x01000000
  8123. +#define AR71XX_EHCI_BASE 0x1b000000
  8124. +#define AR71XX_EHCI_SIZE 0x01000000
  8125. +#define AR71XX_OHCI_BASE 0x1c000000
  8126. +#define AR71XX_OHCI_SIZE 0x01000000
  8127. +#define AR7240_OHCI_BASE 0x1b000000
  8128. +#define AR7240_OHCI_SIZE 0x01000000
  8129. +#define AR71XX_SPI_BASE 0x1f000000
  8130. +#define AR71XX_SPI_SIZE 0x01000000
  8131. +
  8132. +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
  8133. +#define AR71XX_DDR_CTRL_SIZE 0x10000
  8134. +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
  8135. +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  8136. +#define AR71XX_UART_SIZE 0x10000
  8137. +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
  8138. +#define AR71XX_USB_CTRL_SIZE 0x10000
  8139. +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
  8140. +#define AR71XX_GPIO_SIZE 0x10000
  8141. +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
  8142. +#define AR71XX_PLL_SIZE 0x10000
  8143. +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
  8144. +#define AR71XX_RESET_SIZE 0x10000
  8145. +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
  8146. +#define AR71XX_MII_SIZE 0x10000
  8147. +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
  8148. +#define AR71XX_SLIC_SIZE 0x10000
  8149. +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
  8150. +#define AR71XX_DMA_SIZE 0x10000
  8151. +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
  8152. +#define AR71XX_STEREO_SIZE 0x10000
  8153. +
  8154. +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
  8155. +#define AR724X_PCI_CRP_SIZE 0x100
  8156. +
  8157. +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
  8158. +#define AR724X_PCI_CTRL_SIZE 0x100
  8159. +
  8160. +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
  8161. +#define AR91XX_WMAC_SIZE 0x30000
  8162. +
  8163. +#define AR71XX_MEM_SIZE_MIN 0x0200000
  8164. +#define AR71XX_MEM_SIZE_MAX 0x10000000
  8165. +
  8166. +#define AR71XX_CPU_IRQ_BASE 0
  8167. +#define AR71XX_MISC_IRQ_BASE 8
  8168. +#define AR71XX_MISC_IRQ_COUNT 8
  8169. +#define AR71XX_GPIO_IRQ_BASE 16
  8170. +#define AR71XX_GPIO_IRQ_COUNT 32
  8171. +#define AR71XX_PCI_IRQ_BASE 48
  8172. +#define AR71XX_PCI_IRQ_COUNT 8
  8173. +
  8174. +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
  8175. +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
  8176. +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
  8177. +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
  8178. +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
  8179. +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
  8180. +
  8181. +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
  8182. +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
  8183. +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
  8184. +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
  8185. +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
  8186. +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
  8187. +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
  8188. +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
  8189. +
  8190. +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
  8191. +
  8192. +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
  8193. +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
  8194. +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
  8195. +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
  8196. +
  8197. +extern u32 ar71xx_ahb_freq;
  8198. +extern u32 ar71xx_cpu_freq;
  8199. +extern u32 ar71xx_ddr_freq;
  8200. +
  8201. +enum ar71xx_soc_type {
  8202. + AR71XX_SOC_UNKNOWN,
  8203. + AR71XX_SOC_AR7130,
  8204. + AR71XX_SOC_AR7141,
  8205. + AR71XX_SOC_AR7161,
  8206. + AR71XX_SOC_AR7240,
  8207. + AR71XX_SOC_AR7241,
  8208. + AR71XX_SOC_AR7242,
  8209. + AR71XX_SOC_AR9130,
  8210. + AR71XX_SOC_AR9132
  8211. +};
  8212. +
  8213. +extern enum ar71xx_soc_type ar71xx_soc;
  8214. +
  8215. +/*
  8216. + * PLL block
  8217. + */
  8218. +#define AR71XX_PLL_REG_CPU_CONFIG 0x00
  8219. +#define AR71XX_PLL_REG_SEC_CONFIG 0x04
  8220. +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
  8221. +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
  8222. +
  8223. +#define AR71XX_PLL_DIV_SHIFT 3
  8224. +#define AR71XX_PLL_DIV_MASK 0x1f
  8225. +#define AR71XX_CPU_DIV_SHIFT 16
  8226. +#define AR71XX_CPU_DIV_MASK 0x3
  8227. +#define AR71XX_DDR_DIV_SHIFT 18
  8228. +#define AR71XX_DDR_DIV_MASK 0x3
  8229. +#define AR71XX_AHB_DIV_SHIFT 20
  8230. +#define AR71XX_AHB_DIV_MASK 0x7
  8231. +
  8232. +#define AR71XX_ETH0_PLL_SHIFT 17
  8233. +#define AR71XX_ETH1_PLL_SHIFT 19
  8234. +
  8235. +#define AR724X_PLL_REG_CPU_CONFIG 0x00
  8236. +#define AR724X_PLL_REG_PCIE_CONFIG 0x18
  8237. +
  8238. +#define AR724X_PLL_DIV_SHIFT 0
  8239. +#define AR724X_PLL_DIV_MASK 0x3ff
  8240. +#define AR724X_PLL_REF_DIV_SHIFT 10
  8241. +#define AR724X_PLL_REF_DIV_MASK 0xf
  8242. +#define AR724X_AHB_DIV_SHIFT 19
  8243. +#define AR724X_AHB_DIV_MASK 0x1
  8244. +#define AR724X_DDR_DIV_SHIFT 22
  8245. +#define AR724X_DDR_DIV_MASK 0x3
  8246. +
  8247. +#define AR91XX_PLL_REG_CPU_CONFIG 0x00
  8248. +#define AR91XX_PLL_REG_ETH_CONFIG 0x04
  8249. +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
  8250. +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
  8251. +
  8252. +#define AR91XX_PLL_DIV_SHIFT 0
  8253. +#define AR91XX_PLL_DIV_MASK 0x3ff
  8254. +#define AR91XX_DDR_DIV_SHIFT 22
  8255. +#define AR91XX_DDR_DIV_MASK 0x3
  8256. +#define AR91XX_AHB_DIV_SHIFT 19
  8257. +#define AR91XX_AHB_DIV_MASK 0x1
  8258. +
  8259. +#define AR91XX_ETH0_PLL_SHIFT 20
  8260. +#define AR91XX_ETH1_PLL_SHIFT 22
  8261. +
  8262. +extern void __iomem *ar71xx_pll_base;
  8263. +
  8264. +static inline void ar71xx_pll_wr(unsigned reg, u32 val)
  8265. +{
  8266. + __raw_writel(val, ar71xx_pll_base + reg);
  8267. +}
  8268. +
  8269. +static inline u32 ar71xx_pll_rr(unsigned reg)
  8270. +{
  8271. + return __raw_readl(ar71xx_pll_base + reg);
  8272. +}
  8273. +
  8274. +/*
  8275. + * USB_CONFIG block
  8276. + */
  8277. +#define USB_CTRL_REG_FLADJ 0x00
  8278. +#define USB_CTRL_REG_CONFIG 0x04
  8279. +
  8280. +extern void __iomem *ar71xx_usb_ctrl_base;
  8281. +
  8282. +static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
  8283. +{
  8284. + __raw_writel(val, ar71xx_usb_ctrl_base + reg);
  8285. +}
  8286. +
  8287. +static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
  8288. +{
  8289. + return __raw_readl(ar71xx_usb_ctrl_base + reg);
  8290. +}
  8291. +
  8292. +/*
  8293. + * GPIO block
  8294. + */
  8295. +#define GPIO_REG_OE 0x00
  8296. +#define GPIO_REG_IN 0x04
  8297. +#define GPIO_REG_OUT 0x08
  8298. +#define GPIO_REG_SET 0x0c
  8299. +#define GPIO_REG_CLEAR 0x10
  8300. +#define GPIO_REG_INT_MODE 0x14
  8301. +#define GPIO_REG_INT_TYPE 0x18
  8302. +#define GPIO_REG_INT_POLARITY 0x1c
  8303. +#define GPIO_REG_INT_PENDING 0x20
  8304. +#define GPIO_REG_INT_ENABLE 0x24
  8305. +#define GPIO_REG_FUNC 0x28
  8306. +
  8307. +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
  8308. +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
  8309. +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
  8310. +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
  8311. +#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
  8312. +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
  8313. +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
  8314. +
  8315. +#define AR71XX_GPIO_COUNT 16
  8316. +
  8317. +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
  8318. +#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
  8319. +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
  8320. +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
  8321. +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
  8322. +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
  8323. +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
  8324. +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
  8325. +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
  8326. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
  8327. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
  8328. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
  8329. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
  8330. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
  8331. +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
  8332. +#define AR724X_GPIO_FUNC_UART_EN BIT(1)
  8333. +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
  8334. +
  8335. +#define AR724X_GPIO_COUNT 18
  8336. +
  8337. +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
  8338. +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
  8339. +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
  8340. +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
  8341. +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
  8342. +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
  8343. +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
  8344. +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
  8345. +#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
  8346. +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
  8347. +
  8348. +#define AR91XX_GPIO_COUNT 22
  8349. +
  8350. +extern void __iomem *ar71xx_gpio_base;
  8351. +
  8352. +static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
  8353. +{
  8354. + __raw_writel(value, ar71xx_gpio_base + reg);
  8355. +}
  8356. +
  8357. +static inline u32 ar71xx_gpio_rr(unsigned reg)
  8358. +{
  8359. + return __raw_readl(ar71xx_gpio_base + reg);
  8360. +}
  8361. +
  8362. +void ar71xx_gpio_init(void) __init;
  8363. +void ar71xx_gpio_function_enable(u32 mask);
  8364. +void ar71xx_gpio_function_disable(u32 mask);
  8365. +void ar71xx_gpio_function_setup(u32 set, u32 clear);
  8366. +
  8367. +/*
  8368. + * DDR_CTRL block
  8369. + */
  8370. +#define AR71XX_DDR_REG_PCI_WIN0 0x7c
  8371. +#define AR71XX_DDR_REG_PCI_WIN1 0x80
  8372. +#define AR71XX_DDR_REG_PCI_WIN2 0x84
  8373. +#define AR71XX_DDR_REG_PCI_WIN3 0x88
  8374. +#define AR71XX_DDR_REG_PCI_WIN4 0x8c
  8375. +#define AR71XX_DDR_REG_PCI_WIN5 0x90
  8376. +#define AR71XX_DDR_REG_PCI_WIN6 0x94
  8377. +#define AR71XX_DDR_REG_PCI_WIN7 0x98
  8378. +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
  8379. +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
  8380. +#define AR71XX_DDR_REG_FLUSH_USB 0xa4
  8381. +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
  8382. +
  8383. +#define AR724X_DDR_REG_FLUSH_GE0 0x7c
  8384. +#define AR724X_DDR_REG_FLUSH_GE1 0x80
  8385. +#define AR724X_DDR_REG_FLUSH_USB 0x84
  8386. +#define AR724X_DDR_REG_FLUSH_PCIE 0x88
  8387. +
  8388. +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
  8389. +#define AR91XX_DDR_REG_FLUSH_GE1 0x80
  8390. +#define AR91XX_DDR_REG_FLUSH_USB 0x84
  8391. +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
  8392. +
  8393. +#define PCI_WIN0_OFFS 0x10000000
  8394. +#define PCI_WIN1_OFFS 0x11000000
  8395. +#define PCI_WIN2_OFFS 0x12000000
  8396. +#define PCI_WIN3_OFFS 0x13000000
  8397. +#define PCI_WIN4_OFFS 0x14000000
  8398. +#define PCI_WIN5_OFFS 0x15000000
  8399. +#define PCI_WIN6_OFFS 0x16000000
  8400. +#define PCI_WIN7_OFFS 0x07000000
  8401. +
  8402. +extern void __iomem *ar71xx_ddr_base;
  8403. +
  8404. +static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
  8405. +{
  8406. + __raw_writel(val, ar71xx_ddr_base + reg);
  8407. +}
  8408. +
  8409. +static inline u32 ar71xx_ddr_rr(unsigned reg)
  8410. +{
  8411. + return __raw_readl(ar71xx_ddr_base + reg);
  8412. +}
  8413. +
  8414. +void ar71xx_ddr_flush(u32 reg);
  8415. +
  8416. +/*
  8417. + * PCI block
  8418. + */
  8419. +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
  8420. +#define AR71XX_PCI_CFG_SIZE 0x100
  8421. +
  8422. +#define PCI_REG_CRP_AD_CBE 0x00
  8423. +#define PCI_REG_CRP_WRDATA 0x04
  8424. +#define PCI_REG_CRP_RDDATA 0x08
  8425. +#define PCI_REG_CFG_AD 0x0c
  8426. +#define PCI_REG_CFG_CBE 0x10
  8427. +#define PCI_REG_CFG_WRDATA 0x14
  8428. +#define PCI_REG_CFG_RDDATA 0x18
  8429. +#define PCI_REG_PCI_ERR 0x1c
  8430. +#define PCI_REG_PCI_ERR_ADDR 0x20
  8431. +#define PCI_REG_AHB_ERR 0x24
  8432. +#define PCI_REG_AHB_ERR_ADDR 0x28
  8433. +
  8434. +#define PCI_CRP_CMD_WRITE 0x00010000
  8435. +#define PCI_CRP_CMD_READ 0x00000000
  8436. +#define PCI_CFG_CMD_READ 0x0000000a
  8437. +#define PCI_CFG_CMD_WRITE 0x0000000b
  8438. +
  8439. +#define PCI_IDSEL_ADL_START 17
  8440. +
  8441. +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
  8442. +#define AR724X_PCI_CFG_SIZE 0x1000
  8443. +
  8444. +#define AR724X_PCI_REG_APP 0x00
  8445. +#define AR724X_PCI_REG_RESET 0x18
  8446. +#define AR724X_PCI_REG_INT_STATUS 0x4c
  8447. +#define AR724X_PCI_REG_INT_MASK 0x50
  8448. +
  8449. +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
  8450. +#define AR724X_PCI_RESET_LINK_UP BIT(0)
  8451. +
  8452. +#define AR724X_PCI_INT_DEV0 BIT(14)
  8453. +
  8454. +/*
  8455. + * RESET block
  8456. + */
  8457. +#define AR71XX_RESET_REG_TIMER 0x00
  8458. +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
  8459. +#define AR71XX_RESET_REG_WDOG_CTRL 0x08
  8460. +#define AR71XX_RESET_REG_WDOG 0x0c
  8461. +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
  8462. +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
  8463. +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
  8464. +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
  8465. +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
  8466. +#define AR71XX_RESET_REG_RESET_MODULE 0x24
  8467. +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
  8468. +#define AR71XX_RESET_REG_PERFC0 0x30
  8469. +#define AR71XX_RESET_REG_PERFC1 0x34
  8470. +#define AR71XX_RESET_REG_REV_ID 0x90
  8471. +
  8472. +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
  8473. +#define AR91XX_RESET_REG_RESET_MODULE 0x1c
  8474. +#define AR91XX_RESET_REG_PERF_CTRL 0x20
  8475. +#define AR91XX_RESET_REG_PERFC0 0x24
  8476. +#define AR91XX_RESET_REG_PERFC1 0x28
  8477. +
  8478. +#define AR724X_RESET_REG_RESET_MODULE 0x1c
  8479. +
  8480. +#define WDOG_CTRL_LAST_RESET BIT(31)
  8481. +#define WDOG_CTRL_ACTION_MASK 3
  8482. +#define WDOG_CTRL_ACTION_NONE 0 /* no action */
  8483. +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
  8484. +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
  8485. +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
  8486. +
  8487. +#define MISC_INT_DMA BIT(7)
  8488. +#define MISC_INT_OHCI BIT(6)
  8489. +#define MISC_INT_PERFC BIT(5)
  8490. +#define MISC_INT_WDOG BIT(4)
  8491. +#define MISC_INT_UART BIT(3)
  8492. +#define MISC_INT_GPIO BIT(2)
  8493. +#define MISC_INT_ERROR BIT(1)
  8494. +#define MISC_INT_TIMER BIT(0)
  8495. +
  8496. +#define PCI_INT_CORE BIT(4)
  8497. +#define PCI_INT_DEV2 BIT(2)
  8498. +#define PCI_INT_DEV1 BIT(1)
  8499. +#define PCI_INT_DEV0 BIT(0)
  8500. +
  8501. +#define RESET_MODULE_EXTERNAL BIT(28)
  8502. +#define RESET_MODULE_FULL_CHIP BIT(24)
  8503. +#define RESET_MODULE_AMBA2WMAC BIT(22)
  8504. +#define RESET_MODULE_CPU_NMI BIT(21)
  8505. +#define RESET_MODULE_CPU_COLD BIT(20)
  8506. +#define RESET_MODULE_DMA BIT(19)
  8507. +#define RESET_MODULE_SLIC BIT(18)
  8508. +#define RESET_MODULE_STEREO BIT(17)
  8509. +#define RESET_MODULE_DDR BIT(16)
  8510. +#define RESET_MODULE_GE1_MAC BIT(13)
  8511. +#define RESET_MODULE_GE1_PHY BIT(12)
  8512. +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
  8513. +#define RESET_MODULE_GE0_MAC BIT(9)
  8514. +#define RESET_MODULE_GE0_PHY BIT(8)
  8515. +#define RESET_MODULE_USB_OHCI_DLL BIT(6)
  8516. +#define RESET_MODULE_USB_HOST BIT(5)
  8517. +#define RESET_MODULE_USB_PHY BIT(4)
  8518. +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
  8519. +#define RESET_MODULE_PCI_BUS BIT(1)
  8520. +#define RESET_MODULE_PCI_CORE BIT(0)
  8521. +
  8522. +#define AR724X_RESET_GE1_MDIO BIT(23)
  8523. +#define AR724X_RESET_GE0_MDIO BIT(22)
  8524. +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
  8525. +#define AR724X_RESET_PCIE_PHY BIT(7)
  8526. +#define AR724X_RESET_PCIE BIT(6)
  8527. +
  8528. +#define REV_ID_MAJOR_MASK 0xfff0
  8529. +#define REV_ID_MAJOR_AR71XX 0x00a0
  8530. +#define REV_ID_MAJOR_AR913X 0x00b0
  8531. +#define REV_ID_MAJOR_AR7240 0x00c0
  8532. +#define REV_ID_MAJOR_AR7241 0x0100
  8533. +#define REV_ID_MAJOR_AR7242 0x1100
  8534. +
  8535. +#define AR71XX_REV_ID_MINOR_MASK 0x3
  8536. +#define AR71XX_REV_ID_MINOR_AR7130 0x0
  8537. +#define AR71XX_REV_ID_MINOR_AR7141 0x1
  8538. +#define AR71XX_REV_ID_MINOR_AR7161 0x2
  8539. +#define AR71XX_REV_ID_REVISION_MASK 0x3
  8540. +#define AR71XX_REV_ID_REVISION_SHIFT 2
  8541. +
  8542. +#define AR91XX_REV_ID_MINOR_MASK 0x3
  8543. +#define AR91XX_REV_ID_MINOR_AR9130 0x0
  8544. +#define AR91XX_REV_ID_MINOR_AR9132 0x1
  8545. +#define AR91XX_REV_ID_REVISION_MASK 0x3
  8546. +#define AR91XX_REV_ID_REVISION_SHIFT 2
  8547. +
  8548. +#define AR724X_REV_ID_REVISION_MASK 0x3
  8549. +
  8550. +extern void __iomem *ar71xx_reset_base;
  8551. +
  8552. +static inline void ar71xx_reset_wr(unsigned reg, u32 val)
  8553. +{
  8554. + __raw_writel(val, ar71xx_reset_base + reg);
  8555. +}
  8556. +
  8557. +static inline u32 ar71xx_reset_rr(unsigned reg)
  8558. +{
  8559. + return __raw_readl(ar71xx_reset_base + reg);
  8560. +}
  8561. +
  8562. +void ar71xx_device_stop(u32 mask);
  8563. +void ar71xx_device_start(u32 mask);
  8564. +int ar71xx_device_stopped(u32 mask);
  8565. +
  8566. +/*
  8567. + * SPI block
  8568. + */
  8569. +#define SPI_REG_FS 0x00 /* Function Select */
  8570. +#define SPI_REG_CTRL 0x04 /* SPI Control */
  8571. +#define SPI_REG_IOC 0x08 /* SPI I/O Control */
  8572. +#define SPI_REG_RDS 0x0c /* Read Data Shift */
  8573. +
  8574. +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
  8575. +
  8576. +#define SPI_CTRL_RD BIT(6) /* Remap Disable */
  8577. +#define SPI_CTRL_DIV_MASK 0x3f
  8578. +
  8579. +#define SPI_IOC_DO BIT(0) /* Data Out pin */
  8580. +#define SPI_IOC_CLK BIT(8) /* CLK pin */
  8581. +#define SPI_IOC_CS(n) BIT(16 + (n))
  8582. +#define SPI_IOC_CS0 SPI_IOC_CS(0)
  8583. +#define SPI_IOC_CS1 SPI_IOC_CS(1)
  8584. +#define SPI_IOC_CS2 SPI_IOC_CS(2)
  8585. +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
  8586. +
  8587. +void ar71xx_flash_acquire(void);
  8588. +void ar71xx_flash_release(void);
  8589. +
  8590. +/*
  8591. + * MII_CTRL block
  8592. + */
  8593. +#define MII_REG_MII0_CTRL 0x00
  8594. +#define MII_REG_MII1_CTRL 0x04
  8595. +
  8596. +#define MII0_CTRL_IF_GMII 0
  8597. +#define MII0_CTRL_IF_MII 1
  8598. +#define MII0_CTRL_IF_RGMII 2
  8599. +#define MII0_CTRL_IF_RMII 3
  8600. +
  8601. +#define MII1_CTRL_IF_RGMII 0
  8602. +#define MII1_CTRL_IF_RMII 1
  8603. +
  8604. +#endif /* __ASSEMBLER__ */
  8605. +
  8606. +#endif /* __ASM_MACH_AR71XX_H */
  8607. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h
  8608. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100
  8609. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2010-12-17 18:34:51.000000000 +0100
  8610. @@ -0,0 +1,26 @@
  8611. +/*
  8612. + * AR91xx parallel flash driver platform data definitions
  8613. + *
  8614. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8615. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8616. + *
  8617. + * This program is free software; you can redistribute it and/or modify it
  8618. + * under the terms of the GNU General Public License version 2 as published
  8619. + * by the Free Software Foundation.
  8620. + */
  8621. +
  8622. +#ifndef __AR91XX_FLASH_H
  8623. +#define __AR91XX_FLASH_H
  8624. +
  8625. +struct mtd_partition;
  8626. +
  8627. +struct ar91xx_flash_platform_data {
  8628. + unsigned int width;
  8629. + u8 is_shared:1;
  8630. +#ifdef CONFIG_MTD_PARTITIONS
  8631. + unsigned int nr_parts;
  8632. + struct mtd_partition *parts;
  8633. +#endif
  8634. +};
  8635. +
  8636. +#endif /* __AR91XX_FLASH_H */
  8637. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h
  8638. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100
  8639. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2010-12-17 18:34:51.000000000 +0100
  8640. @@ -0,0 +1,56 @@
  8641. +/*
  8642. + * Atheros AR71xx specific CPU feature overrides
  8643. + *
  8644. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8645. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8646. + *
  8647. + * This file was derived from: include/asm-mips/cpu-features.h
  8648. + * Copyright (C) 2003, 2004 Ralf Baechle
  8649. + * Copyright (C) 2004 Maciej W. Rozycki
  8650. + *
  8651. + * This program is free software; you can redistribute it and/or modify it
  8652. + * under the terms of the GNU General Public License version 2 as published
  8653. + * by the Free Software Foundation.
  8654. + *
  8655. + */
  8656. +#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8657. +#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8658. +
  8659. +#define cpu_has_tlb 1
  8660. +#define cpu_has_4kex 1
  8661. +#define cpu_has_3k_cache 0
  8662. +#define cpu_has_4k_cache 1
  8663. +#define cpu_has_tx39_cache 0
  8664. +#define cpu_has_sb1_cache 0
  8665. +#define cpu_has_fpu 0
  8666. +#define cpu_has_32fpr 0
  8667. +#define cpu_has_counter 1
  8668. +#define cpu_has_watch 1
  8669. +#define cpu_has_divec 1
  8670. +
  8671. +#define cpu_has_prefetch 1
  8672. +#define cpu_has_ejtag 1
  8673. +#define cpu_has_llsc 1
  8674. +
  8675. +#define cpu_has_mips16 1
  8676. +#define cpu_has_mdmx 0
  8677. +#define cpu_has_mips3d 0
  8678. +#define cpu_has_smartmips 0
  8679. +
  8680. +#define cpu_has_mips32r1 1
  8681. +#define cpu_has_mips32r2 1
  8682. +#define cpu_has_mips64r1 0
  8683. +#define cpu_has_mips64r2 0
  8684. +
  8685. +#define cpu_has_dsp 0
  8686. +#define cpu_has_mipsmt 0
  8687. +
  8688. +#define cpu_has_64bits 0
  8689. +#define cpu_has_64bit_zero_reg 0
  8690. +#define cpu_has_64bit_gp_regs 0
  8691. +#define cpu_has_64bit_addresses 0
  8692. +
  8693. +#define cpu_dcache_line_size() 32
  8694. +#define cpu_icache_line_size() 32
  8695. +
  8696. +#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */
  8697. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/gpio.h
  8698. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100
  8699. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/gpio.h 2010-12-17 18:34:51.000000000 +0100
  8700. @@ -0,0 +1,53 @@
  8701. +/*
  8702. + * Atheros AR71xx GPIO API definitions
  8703. + *
  8704. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8705. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8706. + *
  8707. + * This program is free software; you can redistribute it and/or modify it
  8708. + * under the terms of the GNU General Public License version 2 as published
  8709. + * by the Free Software Foundation.
  8710. + *
  8711. + */
  8712. +
  8713. +#ifndef __ASM_MACH_AR71XX_GPIO_H
  8714. +#define __ASM_MACH_AR71XX_GPIO_H
  8715. +
  8716. +#define ARCH_NR_GPIOS 64
  8717. +#include <asm-generic/gpio.h>
  8718. +
  8719. +#include <asm/mach-ar71xx/ar71xx.h>
  8720. +
  8721. +extern unsigned long ar71xx_gpio_count;
  8722. +extern void __ar71xx_gpio_set_value(unsigned gpio, int value);
  8723. +extern int __ar71xx_gpio_get_value(unsigned gpio);
  8724. +
  8725. +static inline int gpio_to_irq(unsigned gpio)
  8726. +{
  8727. + return AR71XX_GPIO_IRQ(gpio);
  8728. +}
  8729. +
  8730. +static inline int irq_to_gpio(unsigned irq)
  8731. +{
  8732. + return irq - AR71XX_GPIO_IRQ_BASE;
  8733. +}
  8734. +
  8735. +static inline int gpio_get_value(unsigned gpio)
  8736. +{
  8737. + if (gpio < ar71xx_gpio_count)
  8738. + return __ar71xx_gpio_get_value(gpio);
  8739. +
  8740. + return __gpio_get_value(gpio);
  8741. +}
  8742. +
  8743. +static inline void gpio_set_value(unsigned gpio, int value)
  8744. +{
  8745. + if (gpio < ar71xx_gpio_count)
  8746. + __ar71xx_gpio_set_value(gpio, value);
  8747. + else
  8748. + __gpio_set_value(gpio, value);
  8749. +}
  8750. +
  8751. +#define gpio_cansleep __gpio_cansleep
  8752. +
  8753. +#endif /* __ASM_MACH_AR71XX_GPIO_H */
  8754. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/irq.h
  8755. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100
  8756. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/irq.h 2010-12-17 18:34:51.000000000 +0100
  8757. @@ -0,0 +1,17 @@
  8758. +/*
  8759. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8760. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8761. + *
  8762. + * This program is free software; you can redistribute it and/or modify it
  8763. + * under the terms of the GNU General Public License version 2 as published
  8764. + * by the Free Software Foundation.
  8765. + */
  8766. +#ifndef __ASM_MACH_AR71XX_IRQ_H
  8767. +#define __ASM_MACH_AR71XX_IRQ_H
  8768. +
  8769. +#define MIPS_CPU_IRQ_BASE 0
  8770. +#define NR_IRQS 56
  8771. +
  8772. +#include_next <irq.h>
  8773. +
  8774. +#endif /* __ASM_MACH_AR71XX_IRQ_H */
  8775. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h
  8776. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
  8777. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2010-12-17 18:34:51.000000000 +0100
  8778. @@ -0,0 +1,32 @@
  8779. +/*
  8780. + * Atheros AR71xx specific kernel entry setup
  8781. + *
  8782. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  8783. + *
  8784. + * This program is free software; you can redistribute it and/or modify it
  8785. + * under the terms of the GNU General Public License version 2 as published
  8786. + * by the Free Software Foundation.
  8787. + *
  8788. + */
  8789. +#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8790. +#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8791. +
  8792. + /*
  8793. + * Some bootloaders set the 'Kseg0 coherency algorithm' to
  8794. + * 'Cacheable, noncoherent, write-through, no write allocate'
  8795. + * and this cause performance issues. Let's go and change it to
  8796. + * 'Cacheable, noncoherent, write-back, write allocate'
  8797. + */
  8798. + .macro kernel_entry_setup
  8799. + mfc0 t0, CP0_CONFIG
  8800. + li t1, ~CONF_CM_CMASK
  8801. + and t0, t1
  8802. + ori t0, CONF_CM_CACHABLE_NONCOHERENT
  8803. + mtc0 t0, CP0_CONFIG
  8804. + nop
  8805. + .endm
  8806. +
  8807. + .macro smp_slave_setup
  8808. + .endm
  8809. +
  8810. +#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */
  8811. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/mach-rb750.h
  8812. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100
  8813. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2010-12-17 18:34:51.000000000 +0100
  8814. @@ -0,0 +1,66 @@
  8815. +/*
  8816. + * MikroTik RouterBOARD 750 definitions
  8817. + *
  8818. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  8819. + *
  8820. + * This program is free software; you can redistribute it and/or modify it
  8821. + * under the terms of the GNU General Public License version 2 as published
  8822. + * by the Free Software Foundation.
  8823. + */
  8824. +#ifndef _MACH_RB750_H
  8825. +#define _MACH_RB750_H
  8826. +
  8827. +#include <linux/bitops.h>
  8828. +
  8829. +#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */
  8830. +#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */
  8831. +#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */
  8832. +#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */
  8833. +#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */
  8834. +#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */
  8835. +#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */
  8836. +#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */
  8837. +#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */
  8838. +#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */
  8839. +#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */
  8840. +#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */
  8841. +#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */
  8842. +#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */
  8843. +#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */
  8844. +
  8845. +#define RB750_GPIO_BTN_RESET 1
  8846. +#define RB750_GPIO_SPI_CS0 2
  8847. +#define RB750_GPIO_LED_ACT 12
  8848. +#define RB750_GPIO_LED_PORT1 13
  8849. +#define RB750_GPIO_LED_PORT2 14
  8850. +#define RB750_GPIO_LED_PORT3 15
  8851. +#define RB750_GPIO_LED_PORT4 16
  8852. +#define RB750_GPIO_LED_PORT5 17
  8853. +
  8854. +#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT)
  8855. +#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1)
  8856. +#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2)
  8857. +#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3)
  8858. +#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4)
  8859. +#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5)
  8860. +
  8861. +#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE)
  8862. +
  8863. +#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \
  8864. + RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT)
  8865. +
  8866. +struct rb750_led_data {
  8867. + char *name;
  8868. + char *default_trigger;
  8869. + u32 mask;
  8870. + int active_low;
  8871. +};
  8872. +
  8873. +struct rb750_led_platform_data {
  8874. + int num_leds;
  8875. + struct rb750_led_data *leds;
  8876. +};
  8877. +
  8878. +int rb750_latch_change(u32 mask_clr, u32 mask_set);
  8879. +
  8880. +#endif /* _MACH_RB750_H */
  8881. \ No newline at end of file
  8882. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/mangle-port.h
  8883. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100
  8884. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2010-12-17 18:34:51.000000000 +0100
  8885. @@ -0,0 +1,45 @@
  8886. +/*
  8887. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8888. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8889. + *
  8890. + * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
  8891. + * Copyright (C) 2003, 2004 Ralf Baechle
  8892. + *
  8893. + * This program is free software; you can redistribute it and/or modify it
  8894. + * under the terms of the GNU General Public License version 2 as published
  8895. + * by the Free Software Foundation.
  8896. + */
  8897. +
  8898. +#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H
  8899. +#define __ASM_MACH_AR71XX_MANGLE_PORT_H
  8900. +
  8901. +#define __swizzle_addr_b(port) ((port) ^ 3)
  8902. +#define __swizzle_addr_w(port) ((port) ^ 2)
  8903. +#define __swizzle_addr_l(port) (port)
  8904. +#define __swizzle_addr_q(port) (port)
  8905. +
  8906. +#if defined(CONFIG_SWAP_IO_SPACE)
  8907. +
  8908. +# define ioswabb(a, x) (x)
  8909. +# define __mem_ioswabb(a, x) (x)
  8910. +# define ioswabw(a, x) le16_to_cpu(x)
  8911. +# define __mem_ioswabw(a, x) (x)
  8912. +# define ioswabl(a, x) le32_to_cpu(x)
  8913. +# define __mem_ioswabl(a, x) (x)
  8914. +# define ioswabq(a, x) le64_to_cpu(x)
  8915. +# define __mem_ioswabq(a, x) (x)
  8916. +
  8917. +#else
  8918. +
  8919. +# define ioswabb(a, x) (x)
  8920. +# define __mem_ioswabb(a, x) (x)
  8921. +# define ioswabw(a, x) (x)
  8922. +# define __mem_ioswabw(a, x) cpu_to_le16(x)
  8923. +# define ioswabl(a, x) (x)
  8924. +# define __mem_ioswabl(a, x) cpu_to_le32(x)
  8925. +# define ioswabq(a, x) (x)
  8926. +# define __mem_ioswabq(a, x) cpu_to_le64(x)
  8927. +
  8928. +#endif
  8929. +
  8930. +#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */
  8931. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/pci.h
  8932. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100
  8933. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/pci.h 2010-12-17 18:34:51.000000000 +0100
  8934. @@ -0,0 +1,39 @@
  8935. +/*
  8936. + * Atheros AR71xx SoC specific PCI definitions
  8937. + *
  8938. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8939. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8940. + *
  8941. + * This program is free software; you can redistribute it and/or modify it
  8942. + * under the terms of the GNU General Public License version 2 as published
  8943. + * by the Free Software Foundation.
  8944. + */
  8945. +
  8946. +#ifndef __ASM_MACH_AR71XX_PCI_H
  8947. +#define __ASM_MACH_AR71XX_PCI_H
  8948. +
  8949. +struct pci_dev;
  8950. +
  8951. +struct ar71xx_pci_irq {
  8952. + int irq;
  8953. + u8 slot;
  8954. + u8 pin;
  8955. +};
  8956. +
  8957. +extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  8958. +extern unsigned ar71xx_pci_nr_irqs __initdata;
  8959. +extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  8960. +
  8961. +int ar71xx_pcibios_map_irq(const struct pci_dev *dev,
  8962. + uint8_t slot, uint8_t pin) __init;
  8963. +int ar71xx_pcibios_init(void) __init;
  8964. +
  8965. +int ar71xx_pci_be_handler(int is_fixup);
  8966. +
  8967. +int ar724x_pcibios_map_irq(const struct pci_dev *dev,
  8968. + uint8_t slot, uint8_t pin) __init;
  8969. +int ar724x_pcibios_init(void) __init;
  8970. +
  8971. +int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init;
  8972. +
  8973. +#endif /* __ASM_MACH_AR71XX_PCI_H */
  8974. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/platform.h
  8975. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100
  8976. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/platform.h 2010-12-17 18:34:51.000000000 +0100
  8977. @@ -0,0 +1,61 @@
  8978. +/*
  8979. + * Atheros AR71xx SoC specific platform data definitions
  8980. + *
  8981. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8982. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8983. + *
  8984. + * This program is free software; you can redistribute it and/or modify it
  8985. + * under the terms of the GNU General Public License version 2 as published
  8986. + * by the Free Software Foundation.
  8987. + */
  8988. +
  8989. +#ifndef __ASM_MACH_AR71XX_PLATFORM_H
  8990. +#define __ASM_MACH_AR71XX_PLATFORM_H
  8991. +
  8992. +#include <linux/if_ether.h>
  8993. +#include <linux/skbuff.h>
  8994. +#include <linux/phy.h>
  8995. +#include <linux/spi/spi.h>
  8996. +
  8997. +struct ag71xx_platform_data {
  8998. + phy_interface_t phy_if_mode;
  8999. + u32 phy_mask;
  9000. + int speed;
  9001. + int duplex;
  9002. + u32 reset_bit;
  9003. + u32 mii_if;
  9004. + u8 mac_addr[ETH_ALEN];
  9005. + struct device *mii_bus_dev;
  9006. +
  9007. + u8 has_gbit:1;
  9008. + u8 is_ar91xx:1;
  9009. + u8 is_ar724x:1;
  9010. + u8 has_ar8216:1;
  9011. +
  9012. + void (* ddr_flush)(void);
  9013. + void (* set_pll)(int speed);
  9014. +
  9015. + u32 fifo_cfg1;
  9016. + u32 fifo_cfg2;
  9017. + u32 fifo_cfg3;
  9018. +};
  9019. +
  9020. +struct ag71xx_mdio_platform_data {
  9021. + u32 phy_mask;
  9022. + int is_ar7240;
  9023. +};
  9024. +
  9025. +struct ar71xx_ehci_platform_data {
  9026. + u8 is_ar91xx;
  9027. +};
  9028. +
  9029. +struct ar71xx_spi_platform_data {
  9030. + unsigned bus_num;
  9031. + unsigned num_chipselect;
  9032. + u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on);
  9033. +};
  9034. +
  9035. +#define AR71XX_SPI_CS_INACTIVE 0
  9036. +#define AR71XX_SPI_CS_ACTIVE 1
  9037. +
  9038. +#endif /* __ASM_MACH_AR71XX_PLATFORM_H */
  9039. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.36/arch/mips/include/asm/mach-ar71xx/war.h
  9040. --- linux-2.6.36.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100
  9041. +++ linux-2.6.36/arch/mips/include/asm/mach-ar71xx/war.h 2010-12-17 18:34:51.000000000 +0100
  9042. @@ -0,0 +1,25 @@
  9043. +/*
  9044. + * This file is subject to the terms and conditions of the GNU General Public
  9045. + * License. See the file "COPYING" in the main directory of this archive
  9046. + * for more details.
  9047. + *
  9048. + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  9049. + */
  9050. +#ifndef __ASM_MACH_AR71XX_WAR_H
  9051. +#define __ASM_MACH_AR71XX_WAR_H
  9052. +
  9053. +#define R4600_V1_INDEX_ICACHEOP_WAR 0
  9054. +#define R4600_V1_HIT_CACHEOP_WAR 0
  9055. +#define R4600_V2_HIT_CACHEOP_WAR 0
  9056. +#define R5432_CP0_INTERRUPT_WAR 0
  9057. +#define BCM1250_M3_WAR 0
  9058. +#define SIBYTE_1956_WAR 0
  9059. +#define MIPS4K_ICACHE_REFILL_WAR 0
  9060. +#define MIPS_CACHE_SYNC_WAR 0
  9061. +#define TX49XX_ICACHE_INDEX_INV_WAR 0
  9062. +#define RM9000_CDEX_SMP_WAR 0
  9063. +#define ICACHE_REFILLS_WORKAROUND_WAR 0
  9064. +#define R10000_LLSC_WAR 0
  9065. +#define MIPS34K_MISSED_ITLB_WAR 0
  9066. +
  9067. +#endif /* __ASM_MACH_AR71XX_WAR_H */
  9068. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/mips_machine.h linux-2.6.36/arch/mips/include/asm/mips_machine.h
  9069. --- linux-2.6.36.orig/arch/mips/include/asm/mips_machine.h 1970-01-01 01:00:00.000000000 +0100
  9070. +++ linux-2.6.36/arch/mips/include/asm/mips_machine.h 2010-12-17 18:34:51.000000000 +0100
  9071. @@ -0,0 +1,54 @@
  9072. +/*
  9073. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  9074. + *
  9075. + * This program is free software; you can redistribute it and/or modify it
  9076. + * under the terms of the GNU General Public License version 2 as published
  9077. + * by the Free Software Foundation.
  9078. + *
  9079. + */
  9080. +
  9081. +#ifndef __ASM_MIPS_MACHINE_H
  9082. +#define __ASM_MIPS_MACHINE_H
  9083. +
  9084. +#include <linux/init.h>
  9085. +#include <linux/list.h>
  9086. +
  9087. +#include <asm/bootinfo.h>
  9088. +
  9089. +struct mips_machine {
  9090. + unsigned long mach_type;
  9091. + char *mach_id;
  9092. + char *mach_name;
  9093. + void (*mach_setup)(void);
  9094. + struct list_head list;
  9095. +};
  9096. +
  9097. +void mips_machine_register(struct mips_machine *) __init;
  9098. +void mips_machine_setup(void) __init;
  9099. +int mips_machtype_setup(char *id) __init;
  9100. +void mips_machine_set_name(char *name) __init;
  9101. +
  9102. +extern char *mips_machine_name;
  9103. +
  9104. +#define MIPS_MACHINE(_type, _id, _name, _setup) \
  9105. +static const char machine_name_##_type[] __initconst \
  9106. + __aligned(1) = _name; \
  9107. +static const char machine_id_##_type[] __initconst \
  9108. + __aligned(1) = _id; \
  9109. +static struct mips_machine machine_##_type __initdata = \
  9110. +{ \
  9111. + .mach_type = _type, \
  9112. + .mach_id = (char *) machine_id_##_type, \
  9113. + .mach_name = (char *) machine_name_##_type, \
  9114. + .mach_setup = _setup, \
  9115. +}; \
  9116. + \
  9117. +static int __init register_machine_##_type(void) \
  9118. +{ \
  9119. + mips_machine_register(&machine_##_type); \
  9120. + return 0; \
  9121. +} \
  9122. + \
  9123. +pure_initcall(register_machine_##_type)
  9124. +
  9125. +#endif /* __ASM_MIPS_MACHINE_H */
  9126. diff -Nur linux-2.6.36.orig/arch/mips/include/asm/time.h linux-2.6.36/arch/mips/include/asm/time.h
  9127. --- linux-2.6.36.orig/arch/mips/include/asm/time.h 2010-10-20 22:30:22.000000000 +0200
  9128. +++ linux-2.6.36/arch/mips/include/asm/time.h 2010-12-17 18:34:51.000000000 +0100
  9129. @@ -52,6 +52,7 @@
  9130. */
  9131. #ifdef CONFIG_CEVT_R4K_LIB
  9132. extern unsigned int __weak get_c0_compare_int(void);
  9133. +extern unsigned int __weak get_c0_compare_irq(void);
  9134. extern int r4k_clockevent_init(void);
  9135. #endif
  9136. diff -Nur linux-2.6.36.orig/arch/mips/kernel/Makefile linux-2.6.36/arch/mips/kernel/Makefile
  9137. --- linux-2.6.36.orig/arch/mips/kernel/Makefile 2010-10-20 22:30:22.000000000 +0200
  9138. +++ linux-2.6.36/arch/mips/kernel/Makefile 2010-12-17 18:34:51.000000000 +0100
  9139. @@ -94,6 +94,7 @@
  9140. obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
  9141. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  9142. +obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
  9143. obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
  9144. CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
  9145. diff -Nur linux-2.6.36.orig/arch/mips/kernel/mips_machine.c linux-2.6.36/arch/mips/kernel/mips_machine.c
  9146. --- linux-2.6.36.orig/arch/mips/kernel/mips_machine.c 1970-01-01 01:00:00.000000000 +0100
  9147. +++ linux-2.6.36/arch/mips/kernel/mips_machine.c 2010-12-17 18:34:51.000000000 +0100
  9148. @@ -0,0 +1,121 @@
  9149. +/*
  9150. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  9151. + *
  9152. + * This program is free software; you can redistribute it and/or modify it
  9153. + * under the terms of the GNU General Public License version 2 as published
  9154. + * by the Free Software Foundation.
  9155. + *
  9156. + */
  9157. +#include <linux/mm.h>
  9158. +#include <linux/slab.h>
  9159. +#include <linux/string.h>
  9160. +
  9161. +#include <asm/mips_machine.h>
  9162. +
  9163. +static struct list_head mips_machines __initdata =
  9164. + LIST_HEAD_INIT(mips_machines);
  9165. +static char *mips_machid __initdata;
  9166. +
  9167. +char *mips_machine_name = "Unknown";
  9168. +
  9169. +static struct mips_machine * __init mips_machine_find(unsigned long machtype)
  9170. +{
  9171. + struct list_head *this;
  9172. +
  9173. + list_for_each(this, &mips_machines) {
  9174. + struct mips_machine *mach;
  9175. +
  9176. + mach = list_entry(this, struct mips_machine, list);
  9177. + if (mach->mach_type == machtype)
  9178. + return mach;
  9179. + }
  9180. +
  9181. + return NULL;
  9182. +}
  9183. +
  9184. +void __init mips_machine_register(struct mips_machine *mach)
  9185. +{
  9186. + list_add_tail(&mach->list, &mips_machines);
  9187. +}
  9188. +
  9189. +void __init mips_machine_set_name(char *name)
  9190. +{
  9191. + unsigned int len;
  9192. + char *p;
  9193. +
  9194. + if (name == NULL)
  9195. + return;
  9196. +
  9197. + len = strlen(name);
  9198. + p = kmalloc(len + 1, GFP_KERNEL);
  9199. + if (p) {
  9200. + strncpy(p, name, len);
  9201. + p[len] = '\0';
  9202. + mips_machine_name = p;
  9203. + } else {
  9204. + printk(KERN_WARNING "MIPS: no memory for machine_name\n");
  9205. + }
  9206. +}
  9207. +
  9208. +void __init mips_machine_setup(void)
  9209. +{
  9210. + struct mips_machine *mach;
  9211. +
  9212. + mach = mips_machine_find(mips_machtype);
  9213. + if (!mach) {
  9214. + printk(KERN_WARNING "MIPS: no machine registered for "
  9215. + "machtype %lu\n", mips_machtype);
  9216. + return;
  9217. + }
  9218. +
  9219. + mips_machine_set_name(mach->mach_name);
  9220. + printk(KERN_NOTICE "MIPS: machine is %s\n", mips_machine_name);
  9221. +
  9222. + if (mach->mach_setup)
  9223. + mach->mach_setup();
  9224. +}
  9225. +
  9226. +int __init mips_machtype_setup(char *id)
  9227. +{
  9228. + if (mips_machid == NULL)
  9229. + mips_machid = id;
  9230. +
  9231. + return 1;
  9232. +}
  9233. +
  9234. +__setup("machtype=", mips_machtype_setup);
  9235. +
  9236. +static int __init mips_machtype_init(void)
  9237. +{
  9238. + struct list_head *this;
  9239. + struct mips_machine *mach;
  9240. +
  9241. + if (mips_machid == NULL)
  9242. + return 0;
  9243. +
  9244. + list_for_each(this, &mips_machines) {
  9245. + mach = list_entry(this, struct mips_machine, list);
  9246. + if (mach->mach_id == NULL)
  9247. + continue;
  9248. +
  9249. + if (strcmp(mach->mach_id, mips_machid) == 0) {
  9250. + mips_machtype = mach->mach_type;
  9251. + return 0;
  9252. + }
  9253. + }
  9254. +
  9255. + printk(KERN_WARNING
  9256. + "MIPS: no machine found for id: '%s', registered machines:\n",
  9257. + mips_machid);
  9258. + printk(KERN_WARNING "%32s %s\n", "id", "name");
  9259. +
  9260. + list_for_each(this, &mips_machines) {
  9261. + mach = list_entry(this, struct mips_machine, list);
  9262. + printk(KERN_WARNING "%32s %s\n",
  9263. + mach->mach_id ? mach->mach_id : "", mach->mach_name);
  9264. + }
  9265. +
  9266. + return 0;
  9267. +}
  9268. +
  9269. +core_initcall(mips_machtype_init);
  9270. diff -Nur linux-2.6.36.orig/arch/mips/kernel/proc.c linux-2.6.36/arch/mips/kernel/proc.c
  9271. --- linux-2.6.36.orig/arch/mips/kernel/proc.c 2010-10-20 22:30:22.000000000 +0200
  9272. +++ linux-2.6.36/arch/mips/kernel/proc.c 2010-12-17 18:34:51.000000000 +0100
  9273. @@ -12,6 +12,7 @@
  9274. #include <asm/cpu-features.h>
  9275. #include <asm/mipsregs.h>
  9276. #include <asm/processor.h>
  9277. +#include <asm/mips_machine.h>
  9278. unsigned int vced_count, vcei_count;
  9279. @@ -31,8 +32,12 @@
  9280. /*
  9281. * For the first processor also print the system type
  9282. */
  9283. - if (n == 0)
  9284. + if (n == 0) {
  9285. seq_printf(m, "system type\t\t: %s\n", get_system_type());
  9286. +#ifdef CONFIG_MIPS_MACHINE
  9287. + seq_printf(m, "machine\t\t\t: %s\n", mips_machine_name);
  9288. +#endif
  9289. + }
  9290. seq_printf(m, "processor\t\t: %ld\n", n);
  9291. sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
  9292. diff -Nur linux-2.6.36.orig/arch/mips/kernel/traps.c linux-2.6.36/arch/mips/kernel/traps.c
  9293. --- linux-2.6.36.orig/arch/mips/kernel/traps.c 2010-10-20 22:30:22.000000000 +0200
  9294. +++ linux-2.6.36/arch/mips/kernel/traps.c 2010-12-17 18:34:51.000000000 +0100
  9295. @@ -52,6 +52,7 @@
  9296. #include <asm/types.h>
  9297. #include <asm/stacktrace.h>
  9298. #include <asm/irq.h>
  9299. +#include <asm/time.h>
  9300. #include <asm/uasm.h>
  9301. extern void check_wait(void);
  9302. @@ -1539,6 +1540,8 @@
  9303. if (cpu_has_mips_r2) {
  9304. cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
  9305. cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
  9306. + if (get_c0_compare_irq)
  9307. + cp0_compare_irq = get_c0_compare_irq();
  9308. cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
  9309. if (cp0_perfcount_irq == cp0_compare_irq)
  9310. cp0_perfcount_irq = -1;
  9311. diff -Nur linux-2.6.36.orig/arch/mips/pci/Makefile linux-2.6.36/arch/mips/pci/Makefile
  9312. --- linux-2.6.36.orig/arch/mips/pci/Makefile 2010-10-20 22:30:22.000000000 +0200
  9313. +++ linux-2.6.36/arch/mips/pci/Makefile 2010-12-17 18:34:51.000000000 +0100
  9314. @@ -18,6 +18,7 @@
  9315. obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
  9316. obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
  9317. ops-bcm63xx.o
  9318. +obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o
  9319. #
  9320. # These are still pretty much in the old state, watch, go blind.
  9321. diff -Nur linux-2.6.36.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.36/arch/mips/pci/pci-ar71xx.c
  9322. --- linux-2.6.36.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  9323. +++ linux-2.6.36/arch/mips/pci/pci-ar71xx.c 2010-12-17 18:34:51.000000000 +0100
  9324. @@ -0,0 +1,409 @@
  9325. +/*
  9326. + * Atheros AR71xx PCI host controller driver
  9327. + *
  9328. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  9329. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  9330. + *
  9331. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9332. + *
  9333. + * This program is free software; you can redistribute it and/or modify it
  9334. + * under the terms of the GNU General Public License version 2 as published
  9335. + * by the Free Software Foundation.
  9336. + */
  9337. +
  9338. +#include <linux/resource.h>
  9339. +#include <linux/types.h>
  9340. +#include <linux/delay.h>
  9341. +#include <linux/bitops.h>
  9342. +#include <linux/pci.h>
  9343. +#include <linux/pci_regs.h>
  9344. +#include <linux/interrupt.h>
  9345. +
  9346. +#include <asm/mach-ar71xx/ar71xx.h>
  9347. +#include <asm/mach-ar71xx/pci.h>
  9348. +
  9349. +#undef DEBUG
  9350. +#ifdef DEBUG
  9351. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  9352. +#else
  9353. +#define DBG(fmt, args...)
  9354. +#endif
  9355. +
  9356. +#define AR71XX_PCI_DELAY 100 /* msecs */
  9357. +
  9358. +#if 0
  9359. +#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START
  9360. +#else
  9361. +#define PCI_IDSEL_BASE 0
  9362. +#endif
  9363. +
  9364. +static void __iomem *ar71xx_pcicfg_base;
  9365. +static DEFINE_SPINLOCK(ar71xx_pci_lock);
  9366. +static int ar71xx_pci_fixup_enable;
  9367. +
  9368. +static inline void ar71xx_pci_delay(void)
  9369. +{
  9370. + mdelay(AR71XX_PCI_DELAY);
  9371. +}
  9372. +
  9373. +/* Byte lane enable bits */
  9374. +static u8 ble_table[4][4] = {
  9375. + {0x0, 0xf, 0xf, 0xf},
  9376. + {0xe, 0xd, 0xb, 0x7},
  9377. + {0xc, 0xf, 0x3, 0xf},
  9378. + {0xf, 0xf, 0xf, 0xf},
  9379. +};
  9380. +
  9381. +static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
  9382. +{
  9383. + u32 t;
  9384. +
  9385. + t = ble_table[size & 3][where & 3];
  9386. + BUG_ON(t == 0xf);
  9387. + t <<= (local) ? 20 : 4;
  9388. + return t;
  9389. +}
  9390. +
  9391. +static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
  9392. + int where)
  9393. +{
  9394. + u32 ret;
  9395. +
  9396. + if (!bus->number) {
  9397. + /* type 0 */
  9398. + ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn)))
  9399. + | (PCI_FUNC(devfn) << 8) | (where & ~3);
  9400. + } else {
  9401. + /* type 1 */
  9402. + ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11)
  9403. + | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
  9404. + }
  9405. +
  9406. + return ret;
  9407. +}
  9408. +
  9409. +int ar71xx_pci_be_handler(int is_fixup)
  9410. +{
  9411. + void __iomem *base = ar71xx_pcicfg_base;
  9412. + u32 pci_err;
  9413. + u32 ahb_err;
  9414. +
  9415. + pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3;
  9416. + if (pci_err) {
  9417. + if (!is_fixup)
  9418. + printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n",
  9419. + pci_err,
  9420. + __raw_readl(base + PCI_REG_PCI_ERR_ADDR));
  9421. +
  9422. + __raw_writel(pci_err, base + PCI_REG_PCI_ERR);
  9423. + }
  9424. +
  9425. + ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1;
  9426. + if (ahb_err) {
  9427. + if (!is_fixup)
  9428. + printk(KERN_ALERT "AHB error at AHB address 0x%x\n",
  9429. + __raw_readl(base + PCI_REG_AHB_ERR_ADDR));
  9430. +
  9431. + __raw_writel(ahb_err, base + PCI_REG_AHB_ERR);
  9432. + }
  9433. +
  9434. + return ((ahb_err | pci_err) ? 1 : 0);
  9435. +}
  9436. +
  9437. +static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
  9438. + unsigned int devfn, int where, int size, u32 cmd)
  9439. +{
  9440. + void __iomem *base = ar71xx_pcicfg_base;
  9441. + u32 addr;
  9442. +
  9443. + addr = ar71xx_pci_bus_addr(bus, devfn, where);
  9444. +
  9445. + DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n",
  9446. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9447. + where, size, addr);
  9448. +
  9449. + __raw_writel(addr, base + PCI_REG_CFG_AD);
  9450. + __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
  9451. + base + PCI_REG_CFG_CBE);
  9452. +
  9453. + return ar71xx_pci_be_handler(1);
  9454. +}
  9455. +
  9456. +static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9457. + int where, int size, u32 *value)
  9458. +{
  9459. + void __iomem *base = ar71xx_pcicfg_base;
  9460. + static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
  9461. + unsigned long flags;
  9462. + u32 data;
  9463. + int ret;
  9464. +
  9465. + ret = PCIBIOS_SUCCESSFUL;
  9466. +
  9467. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number,
  9468. + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
  9469. +
  9470. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9471. +
  9472. + if (bus->number == 0 && devfn == 0) {
  9473. + u32 t;
  9474. +
  9475. + t = PCI_CRP_CMD_READ | (where & ~3);
  9476. +
  9477. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9478. + data = __raw_readl(base + PCI_REG_CRP_RDDATA);
  9479. +
  9480. + DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data);
  9481. +
  9482. + } else {
  9483. + int err;
  9484. +
  9485. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9486. + PCI_CFG_CMD_READ);
  9487. +
  9488. + if (err == 0) {
  9489. + data = __raw_readl(base + PCI_REG_CFG_RDDATA);
  9490. + } else {
  9491. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9492. + data = ~0;
  9493. + }
  9494. + }
  9495. +
  9496. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9497. +
  9498. + DBG("PCI: read config: data=%08x raw=%08x\n",
  9499. + (data >> (8 * (where & 3))) & mask[size & 7], data);
  9500. +
  9501. + *value = (data >> (8 * (where & 3))) & mask[size & 7];
  9502. +
  9503. + return ret;
  9504. +}
  9505. +
  9506. +static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9507. + int where, int size, u32 value)
  9508. +{
  9509. + void __iomem *base = ar71xx_pcicfg_base;
  9510. + unsigned long flags;
  9511. + int ret;
  9512. +
  9513. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n",
  9514. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9515. + where, size, value);
  9516. +
  9517. + value = value << (8 * (where & 3));
  9518. + ret = PCIBIOS_SUCCESSFUL;
  9519. +
  9520. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9521. + if (bus->number == 0 && devfn == 0) {
  9522. + u32 t;
  9523. +
  9524. + t = PCI_CRP_CMD_WRITE | (where & ~3);
  9525. + t |= ar71xx_pci_get_ble(where, size, 1);
  9526. +
  9527. + DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value);
  9528. +
  9529. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9530. + __raw_writel(value, base + PCI_REG_CRP_WRDATA);
  9531. + } else {
  9532. + int err;
  9533. +
  9534. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9535. + PCI_CFG_CMD_WRITE);
  9536. +
  9537. + if (err == 0)
  9538. + __raw_writel(value, base + PCI_REG_CFG_WRDATA);
  9539. + else
  9540. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9541. + }
  9542. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9543. +
  9544. + return ret;
  9545. +}
  9546. +
  9547. +static void ar71xx_pci_fixup(struct pci_dev *dev)
  9548. +{
  9549. + u32 t;
  9550. +
  9551. + if (!ar71xx_pci_fixup_enable)
  9552. + return;
  9553. +
  9554. + if (dev->bus->number != 0 || dev->devfn != 0)
  9555. + return;
  9556. +
  9557. + DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev),
  9558. + dev->vendor, dev->device);
  9559. +
  9560. + /* setup COMMAND register */
  9561. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
  9562. + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
  9563. +
  9564. + pci_write_config_word(dev, PCI_COMMAND, t);
  9565. +}
  9566. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup);
  9567. +
  9568. +int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9569. + uint8_t pin)
  9570. +{
  9571. + int irq = -1;
  9572. + int i;
  9573. +
  9574. + slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE;
  9575. +
  9576. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9577. + struct ar71xx_pci_irq *entry;
  9578. +
  9579. + entry = &ar71xx_pci_irq_map[i];
  9580. + if (entry->slot == slot && entry->pin == pin) {
  9581. + irq = entry->irq;
  9582. + break;
  9583. + }
  9584. + }
  9585. +
  9586. + if (irq < 0) {
  9587. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9588. + pin, pci_name((struct pci_dev *)dev));
  9589. + } else {
  9590. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9591. + irq, pin, pci_name((struct pci_dev *)dev));
  9592. + }
  9593. +
  9594. + return irq;
  9595. +}
  9596. +
  9597. +static struct pci_ops ar71xx_pci_ops = {
  9598. + .read = ar71xx_pci_read_config,
  9599. + .write = ar71xx_pci_write_config,
  9600. +};
  9601. +
  9602. +static struct resource ar71xx_pci_io_resource = {
  9603. + .name = "PCI IO space",
  9604. + .start = 0,
  9605. + .end = 0,
  9606. + .flags = IORESOURCE_IO,
  9607. +};
  9608. +
  9609. +static struct resource ar71xx_pci_mem_resource = {
  9610. + .name = "PCI memory space",
  9611. + .start = AR71XX_PCI_MEM_BASE,
  9612. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9613. + .flags = IORESOURCE_MEM
  9614. +};
  9615. +
  9616. +static struct pci_controller ar71xx_pci_controller = {
  9617. + .pci_ops = &ar71xx_pci_ops,
  9618. + .mem_resource = &ar71xx_pci_mem_resource,
  9619. + .io_resource = &ar71xx_pci_io_resource,
  9620. +};
  9621. +
  9622. +static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  9623. +{
  9624. + void __iomem *base = ar71xx_reset_base;
  9625. + u32 pending;
  9626. +
  9627. + pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
  9628. + __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9629. +
  9630. + if (pending & PCI_INT_DEV0)
  9631. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  9632. +
  9633. + else if (pending & PCI_INT_DEV1)
  9634. + generic_handle_irq(AR71XX_PCI_IRQ_DEV1);
  9635. +
  9636. + else if (pending & PCI_INT_DEV2)
  9637. + generic_handle_irq(AR71XX_PCI_IRQ_DEV2);
  9638. +
  9639. + else if (pending & PCI_INT_CORE)
  9640. + generic_handle_irq(AR71XX_PCI_IRQ_CORE);
  9641. +
  9642. + else
  9643. + spurious_interrupt();
  9644. +}
  9645. +
  9646. +static void ar71xx_pci_irq_unmask(unsigned int irq)
  9647. +{
  9648. + void __iomem *base = ar71xx_reset_base;
  9649. + u32 t;
  9650. +
  9651. + irq -= AR71XX_PCI_IRQ_BASE;
  9652. +
  9653. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9654. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9655. +
  9656. + /* flush write */
  9657. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9658. +}
  9659. +
  9660. +static void ar71xx_pci_irq_mask(unsigned int irq)
  9661. +{
  9662. + void __iomem *base = ar71xx_reset_base;
  9663. + u32 t;
  9664. +
  9665. + irq -= AR71XX_PCI_IRQ_BASE;
  9666. +
  9667. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9668. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9669. +
  9670. + /* flush write */
  9671. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9672. +}
  9673. +
  9674. +static struct irq_chip ar71xx_pci_irq_chip = {
  9675. + .name = "AR71XX PCI ",
  9676. + .mask = ar71xx_pci_irq_mask,
  9677. + .unmask = ar71xx_pci_irq_unmask,
  9678. + .mask_ack = ar71xx_pci_irq_mask,
  9679. +};
  9680. +
  9681. +static void __init ar71xx_pci_irq_init(void)
  9682. +{
  9683. + void __iomem *base = ar71xx_reset_base;
  9684. + int i;
  9685. +
  9686. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9687. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
  9688. +
  9689. + for (i = AR71XX_PCI_IRQ_BASE;
  9690. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  9691. + irq_desc[i].status = IRQ_DISABLED;
  9692. + set_irq_chip_and_handler(i, &ar71xx_pci_irq_chip,
  9693. + handle_level_irq);
  9694. + }
  9695. +
  9696. + set_irq_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
  9697. +}
  9698. +
  9699. +int __init ar71xx_pcibios_init(void)
  9700. +{
  9701. + void __iomem *ddr_base = ar71xx_ddr_base;
  9702. +
  9703. + ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9704. + ar71xx_pci_delay();
  9705. +
  9706. + ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9707. + ar71xx_pci_delay();
  9708. +
  9709. + ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE,
  9710. + AR71XX_PCI_CFG_SIZE);
  9711. + if (ar71xx_pcicfg_base == NULL)
  9712. + return -ENOMEM;
  9713. +
  9714. + __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
  9715. + __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
  9716. + __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
  9717. + __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
  9718. + __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
  9719. + __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
  9720. + __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
  9721. + __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
  9722. +
  9723. + ar71xx_pci_delay();
  9724. +
  9725. + /* clear bus errors */
  9726. + (void)ar71xx_pci_be_handler(1);
  9727. +
  9728. + ar71xx_pci_fixup_enable = 1;
  9729. + ar71xx_pci_irq_init();
  9730. + register_pci_controller(&ar71xx_pci_controller);
  9731. +
  9732. + return 0;
  9733. +}
  9734. diff -Nur linux-2.6.36.orig/arch/mips/pci/pci-ar724x.c linux-2.6.36/arch/mips/pci/pci-ar724x.c
  9735. --- linux-2.6.36.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100
  9736. +++ linux-2.6.36/arch/mips/pci/pci-ar724x.c 2010-12-17 18:34:51.000000000 +0100
  9737. @@ -0,0 +1,395 @@
  9738. +/*
  9739. + * Atheros AR724x PCI host controller driver
  9740. + *
  9741. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  9742. + *
  9743. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9744. + *
  9745. + * This program is free software; you can redistribute it and/or modify it
  9746. + * under the terms of the GNU General Public License version 2 as published
  9747. + * by the Free Software Foundation.
  9748. + */
  9749. +
  9750. +#include <linux/resource.h>
  9751. +#include <linux/types.h>
  9752. +#include <linux/delay.h>
  9753. +#include <linux/bitops.h>
  9754. +#include <linux/pci.h>
  9755. +#include <linux/pci_regs.h>
  9756. +#include <linux/interrupt.h>
  9757. +
  9758. +#include <asm/mach-ar71xx/ar71xx.h>
  9759. +#include <asm/mach-ar71xx/pci.h>
  9760. +
  9761. +#undef DEBUG
  9762. +#ifdef DEBUG
  9763. +#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args)
  9764. +#else
  9765. +#define DBG(fmt, args...)
  9766. +#endif
  9767. +
  9768. +static void __iomem *ar724x_pci_localcfg_base;
  9769. +static void __iomem *ar724x_pci_devcfg_base;
  9770. +static void __iomem *ar724x_pci_ctrl_base;
  9771. +static int ar724x_pci_fixup_enable;
  9772. +
  9773. +static DEFINE_SPINLOCK(ar724x_pci_lock);
  9774. +
  9775. +static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value)
  9776. +{
  9777. + unsigned long flags;
  9778. + u32 data;
  9779. +
  9780. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9781. + data = __raw_readl(base + (where & ~3));
  9782. +
  9783. + switch (size) {
  9784. + case 1:
  9785. + if (where & 1)
  9786. + data >>= 8;
  9787. + if (where & 2)
  9788. + data >>= 16;
  9789. + data &= 0xFF;
  9790. + break;
  9791. + case 2:
  9792. + if (where & 2)
  9793. + data >>= 16;
  9794. + data &= 0xFFFF;
  9795. + break;
  9796. + }
  9797. +
  9798. + *value = data;
  9799. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9800. +}
  9801. +
  9802. +static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value)
  9803. +{
  9804. + unsigned long flags;
  9805. + u32 data;
  9806. + int s;
  9807. +
  9808. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9809. + data = __raw_readl(base + (where & ~3));
  9810. +
  9811. + switch (size) {
  9812. + case 1:
  9813. + s = ((where & 3) << 3);
  9814. + data &= ~(0xFF << s);
  9815. + data |= ((value & 0xFF) << s);
  9816. + break;
  9817. + case 2:
  9818. + s = ((where & 2) << 3);
  9819. + data &= ~(0xFFFF << s);
  9820. + data |= ((value & 0xFFFF) << s);
  9821. + break;
  9822. + case 4:
  9823. + data = value;
  9824. + break;
  9825. + }
  9826. +
  9827. + __raw_writel(data, base + (where & ~3));
  9828. + /* flush write */
  9829. + (void)__raw_readl(base + (where & ~3));
  9830. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9831. +}
  9832. +
  9833. +static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9834. + int where, int size, u32 *value)
  9835. +{
  9836. +
  9837. + if (bus->number != 0 || devfn != 0)
  9838. + return PCIBIOS_DEVICE_NOT_FOUND;
  9839. +
  9840. + ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value);
  9841. +
  9842. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9843. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9844. + where, size, *value);
  9845. +
  9846. + /*
  9847. + * WAR for BAR issue - We are unable to access the PCI device space
  9848. + * if we set the BAR with proper base address
  9849. + */
  9850. + if ((where == 0x10) && (size == 4)) {
  9851. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9852. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0xffff);
  9853. + else
  9854. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0x1000ffff);
  9855. + }
  9856. +
  9857. + return PCIBIOS_SUCCESSFUL;
  9858. +}
  9859. +
  9860. +static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9861. + int where, int size, u32 value)
  9862. +{
  9863. + if (bus->number != 0 || devfn != 0)
  9864. + return PCIBIOS_DEVICE_NOT_FOUND;
  9865. +
  9866. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9867. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9868. + where, size, value);
  9869. +
  9870. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value);
  9871. +
  9872. + return PCIBIOS_SUCCESSFUL;
  9873. +}
  9874. +
  9875. +static void ar724x_pci_fixup(struct pci_dev *dev)
  9876. +{
  9877. + u16 cmd;
  9878. +
  9879. + if (!ar724x_pci_fixup_enable)
  9880. + return;
  9881. +
  9882. + if (dev->bus->number != 0 || dev->devfn != 0)
  9883. + return;
  9884. +
  9885. + /* setup COMMAND register */
  9886. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  9887. + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
  9888. + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
  9889. + PCI_COMMAND_FAST_BACK;
  9890. +
  9891. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  9892. +}
  9893. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup);
  9894. +
  9895. +int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9896. + uint8_t pin)
  9897. +{
  9898. + int irq = -1;
  9899. + int i;
  9900. +
  9901. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9902. + struct ar71xx_pci_irq *entry;
  9903. + entry = &ar71xx_pci_irq_map[i];
  9904. +
  9905. + if (entry->slot == slot && entry->pin == pin) {
  9906. + irq = entry->irq;
  9907. + break;
  9908. + }
  9909. + }
  9910. +
  9911. + if (irq < 0)
  9912. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9913. + pin, pci_name((struct pci_dev *)dev));
  9914. + else
  9915. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9916. + irq, pin, pci_name((struct pci_dev *)dev));
  9917. +
  9918. + return irq;
  9919. +}
  9920. +
  9921. +static struct pci_ops ar724x_pci_ops = {
  9922. + .read = ar724x_pci_read_config,
  9923. + .write = ar724x_pci_write_config,
  9924. +};
  9925. +
  9926. +static struct resource ar724x_pci_io_resource = {
  9927. + .name = "PCI IO space",
  9928. + .start = 0,
  9929. + .end = 0,
  9930. + .flags = IORESOURCE_IO,
  9931. +};
  9932. +
  9933. +static struct resource ar724x_pci_mem_resource = {
  9934. + .name = "PCI memory space",
  9935. + .start = AR71XX_PCI_MEM_BASE,
  9936. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9937. + .flags = IORESOURCE_MEM
  9938. +};
  9939. +
  9940. +static struct pci_controller ar724x_pci_controller = {
  9941. + .pci_ops = &ar724x_pci_ops,
  9942. + .mem_resource = &ar724x_pci_mem_resource,
  9943. + .io_resource = &ar724x_pci_io_resource,
  9944. +};
  9945. +
  9946. +static void __init ar724x_pci_reset(void)
  9947. +{
  9948. + ar71xx_device_stop(AR724X_RESET_PCIE);
  9949. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY);
  9950. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL);
  9951. + udelay(100);
  9952. +
  9953. + ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL);
  9954. + udelay(100);
  9955. + ar71xx_device_start(AR724X_RESET_PCIE_PHY);
  9956. + ar71xx_device_start(AR724X_RESET_PCIE);
  9957. +}
  9958. +
  9959. +static int __init ar724x_pci_setup(void)
  9960. +{
  9961. + void __iomem *base = ar724x_pci_ctrl_base;
  9962. + u32 t;
  9963. +
  9964. + /* setup COMMAND register */
  9965. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE |
  9966. + PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK;
  9967. +
  9968. + ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t);
  9969. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000);
  9970. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000);
  9971. +
  9972. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9973. + if (t != 0x7) {
  9974. + udelay(100000);
  9975. + __raw_writel(0, base + AR724X_PCI_REG_RESET);
  9976. + udelay(100);
  9977. + __raw_writel(4, base + AR724X_PCI_REG_RESET);
  9978. + udelay(100000);
  9979. + }
  9980. +
  9981. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9982. + t = AR724X_PCI_APP_LTSSM_ENABLE;
  9983. + else
  9984. + t = 0x1ffc1;
  9985. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  9986. + /* flush write */
  9987. + (void) __raw_readl(base + AR724X_PCI_REG_APP);
  9988. + udelay(1000);
  9989. +
  9990. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9991. + if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) {
  9992. + printk(KERN_WARNING "PCI: no PCIe module found\n");
  9993. + return -ENODEV;
  9994. + }
  9995. +
  9996. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  9997. + t = __raw_readl(base + AR724X_PCI_REG_APP);
  9998. + t |= BIT(16);
  9999. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  10000. + }
  10001. +
  10002. + return 0;
  10003. +}
  10004. +
  10005. +static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  10006. +{
  10007. + void __iomem *base = ar724x_pci_ctrl_base;
  10008. + u32 pending;
  10009. +
  10010. + pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
  10011. + __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10012. +
  10013. + if (pending & AR724X_PCI_INT_DEV0)
  10014. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  10015. +
  10016. + else
  10017. + spurious_interrupt();
  10018. +}
  10019. +
  10020. +static void ar724x_pci_irq_unmask(unsigned int irq)
  10021. +{
  10022. + void __iomem *base = ar724x_pci_ctrl_base;
  10023. + u32 t;
  10024. +
  10025. + switch (irq) {
  10026. + case AR71XX_PCI_IRQ_DEV0:
  10027. + irq -= AR71XX_PCI_IRQ_BASE;
  10028. +
  10029. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10030. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  10031. + base + AR724X_PCI_REG_INT_MASK);
  10032. + /* flush write */
  10033. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10034. + }
  10035. +}
  10036. +
  10037. +static void ar724x_pci_irq_mask(unsigned int irq)
  10038. +{
  10039. + void __iomem *base = ar724x_pci_ctrl_base;
  10040. + u32 t;
  10041. +
  10042. + switch (irq) {
  10043. + case AR71XX_PCI_IRQ_DEV0:
  10044. + irq -= AR71XX_PCI_IRQ_BASE;
  10045. +
  10046. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10047. + __raw_writel(t & ~AR724X_PCI_INT_DEV0,
  10048. + base + AR724X_PCI_REG_INT_MASK);
  10049. +
  10050. + /* flush write */
  10051. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10052. +
  10053. + t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  10054. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  10055. + base + AR724X_PCI_REG_INT_STATUS);
  10056. +
  10057. + /* flush write */
  10058. + (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  10059. + }
  10060. +}
  10061. +
  10062. +static struct irq_chip ar724x_pci_irq_chip = {
  10063. + .name = "AR724X PCI ",
  10064. + .mask = ar724x_pci_irq_mask,
  10065. + .unmask = ar724x_pci_irq_unmask,
  10066. + .mask_ack = ar724x_pci_irq_mask,
  10067. +};
  10068. +
  10069. +static void __init ar724x_pci_irq_init(void)
  10070. +{
  10071. + void __iomem *base = ar724x_pci_ctrl_base;
  10072. + u32 t;
  10073. + int i;
  10074. +
  10075. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  10076. + if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY |
  10077. + AR724X_RESET_PCIE_PHY_SERIAL)) {
  10078. + return;
  10079. + }
  10080. +
  10081. + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
  10082. + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
  10083. +
  10084. + for (i = AR71XX_PCI_IRQ_BASE;
  10085. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  10086. + irq_desc[i].status = IRQ_DISABLED;
  10087. + set_irq_chip_and_handler(i, &ar724x_pci_irq_chip,
  10088. + handle_level_irq);
  10089. + }
  10090. +
  10091. + set_irq_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler);
  10092. +}
  10093. +
  10094. +int __init ar724x_pcibios_init(void)
  10095. +{
  10096. + int ret = -ENOMEM;
  10097. +
  10098. + ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE,
  10099. + AR724X_PCI_CRP_SIZE);
  10100. + if (ar724x_pci_localcfg_base == NULL)
  10101. + goto err;
  10102. +
  10103. + ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE,
  10104. + AR724X_PCI_CFG_SIZE);
  10105. + if (ar724x_pci_devcfg_base == NULL)
  10106. + goto err_unmap_localcfg;
  10107. +
  10108. + ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE,
  10109. + AR724X_PCI_CTRL_SIZE);
  10110. + if (ar724x_pci_ctrl_base == NULL)
  10111. + goto err_unmap_devcfg;
  10112. +
  10113. + ar724x_pci_reset();
  10114. + ret = ar724x_pci_setup();
  10115. + if (ret)
  10116. + goto err_unmap_ctrl;
  10117. +
  10118. + ar724x_pci_fixup_enable = 1;
  10119. + ar724x_pci_irq_init();
  10120. + register_pci_controller(&ar724x_pci_controller);
  10121. +
  10122. + return 0;
  10123. +
  10124. + err_unmap_ctrl:
  10125. + iounmap(ar724x_pci_ctrl_base);
  10126. + err_unmap_devcfg:
  10127. + iounmap(ar724x_pci_devcfg_base);
  10128. + err_unmap_localcfg:
  10129. + iounmap(ar724x_pci_localcfg_base);
  10130. + err:
  10131. + return ret;
  10132. +}
  10133. diff -Nur linux-2.6.36.orig/drivers/char/Kconfig linux-2.6.36/drivers/char/Kconfig
  10134. --- linux-2.6.36.orig/drivers/char/Kconfig 2010-10-20 22:30:22.000000000 +0200
  10135. +++ linux-2.6.36/drivers/char/Kconfig 2010-12-17 18:34:51.000000000 +0100
  10136. @@ -1032,6 +1032,14 @@
  10137. If compiled as a module, it will be called cs5535_gpio.
  10138. +config GPIO_DEVICE
  10139. + tristate "GPIO device support"
  10140. + depends on GENERIC_GPIO
  10141. + help
  10142. + Say Y to enable Linux GPIO device support. This allows control of
  10143. + GPIO pins using a character device
  10144. +
  10145. +
  10146. config RAW_DRIVER
  10147. tristate "RAW driver (/dev/raw/rawN)"
  10148. depends on BLOCK
  10149. diff -Nur linux-2.6.36.orig/drivers/char/Makefile linux-2.6.36/drivers/char/Makefile
  10150. --- linux-2.6.36.orig/drivers/char/Makefile 2010-10-20 22:30:22.000000000 +0200
  10151. +++ linux-2.6.36/drivers/char/Makefile 2010-12-17 18:34:51.000000000 +0100
  10152. @@ -98,6 +98,7 @@
  10153. obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
  10154. obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
  10155. obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
  10156. +obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o
  10157. obj-$(CONFIG_GPIO_TB0219) += tb0219.o
  10158. obj-$(CONFIG_TELCLOCK) += tlclk.o
  10159. diff -Nur linux-2.6.36.orig/drivers/gpio/nxp_74hc153.c linux-2.6.36/drivers/gpio/nxp_74hc153.c
  10160. --- linux-2.6.36.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100
  10161. +++ linux-2.6.36/drivers/gpio/nxp_74hc153.c 2010-12-17 18:34:51.000000000 +0100
  10162. @@ -0,0 +1,246 @@
  10163. +/*
  10164. + * NXP 74HC153 - Dual 4-input multiplexer GPIO driver
  10165. + *
  10166. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  10167. + *
  10168. + * This program is free software; you can redistribute it and/or modify
  10169. + * it under the terms of the GNU General Public License version 2 as
  10170. + * published by the Free Software Foundation.
  10171. + */
  10172. +
  10173. +#include <linux/module.h>
  10174. +#include <linux/init.h>
  10175. +#include <linux/gpio.h>
  10176. +#include <linux/platform_device.h>
  10177. +#include <linux/nxp_74hc153.h>
  10178. +
  10179. +#define NXP_74HC153_NUM_GPIOS 8
  10180. +#define NXP_74HC153_S0_MASK 0x1
  10181. +#define NXP_74HC153_S1_MASK 0x2
  10182. +#define NXP_74HC153_BANK_MASK 0x4
  10183. +
  10184. +struct nxp_74hc153_chip {
  10185. + struct device *parent;
  10186. + struct gpio_chip gpio_chip;
  10187. + struct mutex lock;
  10188. +};
  10189. +
  10190. +static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc)
  10191. +{
  10192. + return container_of(gc, struct nxp_74hc153_chip, gpio_chip);
  10193. +}
  10194. +
  10195. +static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset)
  10196. +{
  10197. + return 0;
  10198. +}
  10199. +
  10200. +static int nxp_74hc153_direction_output(struct gpio_chip *gc,
  10201. + unsigned offset, int val)
  10202. +{
  10203. + return -EINVAL;
  10204. +}
  10205. +
  10206. +static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset)
  10207. +{
  10208. + struct nxp_74hc153_chip *nxp;
  10209. + struct nxp_74hc153_platform_data *pdata;
  10210. + unsigned s0;
  10211. + unsigned s1;
  10212. + unsigned pin;
  10213. + int ret;
  10214. +
  10215. + nxp = gpio_to_nxp(gc);
  10216. + pdata = nxp->parent->platform_data;
  10217. +
  10218. + s0 = !!(offset & NXP_74HC153_S0_MASK);
  10219. + s1 = !!(offset & NXP_74HC153_S1_MASK);
  10220. + pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y
  10221. + : pdata->gpio_pin_1y;
  10222. +
  10223. + mutex_lock(&nxp->lock);
  10224. + gpio_set_value(pdata->gpio_pin_s0, s0);
  10225. + gpio_set_value(pdata->gpio_pin_s1, s1);
  10226. + ret = gpio_get_value(pin);
  10227. + mutex_unlock(&nxp->lock);
  10228. +
  10229. + return ret;
  10230. +}
  10231. +
  10232. +static void nxp_74hc153_set_value(struct gpio_chip *gc,
  10233. + unsigned offset, int val)
  10234. +{
  10235. + /* not supported */
  10236. +}
  10237. +
  10238. +static int __devinit nxp_74hc153_probe(struct platform_device *pdev)
  10239. +{
  10240. + struct nxp_74hc153_platform_data *pdata;
  10241. + struct nxp_74hc153_chip *nxp;
  10242. + struct gpio_chip *gc;
  10243. + int err;
  10244. +
  10245. + pdata = pdev->dev.platform_data;
  10246. + if (pdata == NULL) {
  10247. + dev_dbg(&pdev->dev, "no platform data specified\n");
  10248. + return -EINVAL;
  10249. + }
  10250. +
  10251. + nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL);
  10252. + if (nxp == NULL) {
  10253. + dev_err(&pdev->dev, "no memory for private data\n");
  10254. + return -ENOMEM;
  10255. + }
  10256. +
  10257. + err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev));
  10258. + if (err) {
  10259. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10260. + pdata->gpio_pin_s0, err);
  10261. + goto err_free_nxp;
  10262. + }
  10263. +
  10264. + err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev));
  10265. + if (err) {
  10266. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10267. + pdata->gpio_pin_s1, err);
  10268. + goto err_free_s0;
  10269. + }
  10270. +
  10271. + err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev));
  10272. + if (err) {
  10273. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10274. + pdata->gpio_pin_1y, err);
  10275. + goto err_free_s1;
  10276. + }
  10277. +
  10278. + err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev));
  10279. + if (err) {
  10280. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10281. + pdata->gpio_pin_2y, err);
  10282. + goto err_free_1y;
  10283. + }
  10284. +
  10285. + err = gpio_direction_output(pdata->gpio_pin_s0, 0);
  10286. + if (err) {
  10287. + dev_err(&pdev->dev,
  10288. + "unable to set direction of gpio %u, err=%d\n",
  10289. + pdata->gpio_pin_s0, err);
  10290. + goto err_free_2y;
  10291. + }
  10292. +
  10293. + err = gpio_direction_output(pdata->gpio_pin_s1, 0);
  10294. + if (err) {
  10295. + dev_err(&pdev->dev,
  10296. + "unable to set direction of gpio %u, err=%d\n",
  10297. + pdata->gpio_pin_s1, err);
  10298. + goto err_free_2y;
  10299. + }
  10300. +
  10301. + err = gpio_direction_input(pdata->gpio_pin_1y);
  10302. + if (err) {
  10303. + dev_err(&pdev->dev,
  10304. + "unable to set direction of gpio %u, err=%d\n",
  10305. + pdata->gpio_pin_1y, err);
  10306. + goto err_free_2y;
  10307. + }
  10308. +
  10309. + err = gpio_direction_input(pdata->gpio_pin_2y);
  10310. + if (err) {
  10311. + dev_err(&pdev->dev,
  10312. + "unable to set direction of gpio %u, err=%d\n",
  10313. + pdata->gpio_pin_2y, err);
  10314. + goto err_free_2y;
  10315. + }
  10316. +
  10317. + nxp->parent = &pdev->dev;
  10318. + mutex_init(&nxp->lock);
  10319. +
  10320. + gc = &nxp->gpio_chip;
  10321. +
  10322. + gc->direction_input = nxp_74hc153_direction_input;
  10323. + gc->direction_output = nxp_74hc153_direction_output;
  10324. + gc->get = nxp_74hc153_get_value;
  10325. + gc->set = nxp_74hc153_set_value;
  10326. + gc->can_sleep = 1;
  10327. +
  10328. + gc->base = pdata->gpio_base;
  10329. + gc->ngpio = NXP_74HC153_NUM_GPIOS;
  10330. + gc->label = dev_name(nxp->parent);
  10331. + gc->dev = nxp->parent;
  10332. + gc->owner = THIS_MODULE;
  10333. +
  10334. + err = gpiochip_add(&nxp->gpio_chip);
  10335. + if (err) {
  10336. + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
  10337. + goto err_free_2y;
  10338. + }
  10339. +
  10340. + platform_set_drvdata(pdev, nxp);
  10341. + return 0;
  10342. +
  10343. + err_free_2y:
  10344. + gpio_free(pdata->gpio_pin_2y);
  10345. + err_free_1y:
  10346. + gpio_free(pdata->gpio_pin_1y);
  10347. + err_free_s1:
  10348. + gpio_free(pdata->gpio_pin_s1);
  10349. + err_free_s0:
  10350. + gpio_free(pdata->gpio_pin_s0);
  10351. + err_free_nxp:
  10352. + kfree(nxp);
  10353. + return err;
  10354. +}
  10355. +
  10356. +static int nxp_74hc153_remove(struct platform_device *pdev)
  10357. +{
  10358. + struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev);
  10359. + struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data;
  10360. +
  10361. + if (nxp) {
  10362. + int err;
  10363. +
  10364. + err = gpiochip_remove(&nxp->gpio_chip);
  10365. + if (err) {
  10366. + dev_err(&pdev->dev,
  10367. + "unable to remove gpio chip, err=%d\n",
  10368. + err);
  10369. + return err;
  10370. + }
  10371. +
  10372. + gpio_free(pdata->gpio_pin_2y);
  10373. + gpio_free(pdata->gpio_pin_1y);
  10374. + gpio_free(pdata->gpio_pin_s1);
  10375. + gpio_free(pdata->gpio_pin_s0);
  10376. +
  10377. + kfree(nxp);
  10378. + platform_set_drvdata(pdev, NULL);
  10379. + }
  10380. +
  10381. + return 0;
  10382. +}
  10383. +
  10384. +static struct platform_driver nxp_74hc153_driver = {
  10385. + .probe = nxp_74hc153_probe,
  10386. + .remove = __devexit_p(nxp_74hc153_remove),
  10387. + .driver = {
  10388. + .name = NXP_74HC153_DRIVER_NAME,
  10389. + .owner = THIS_MODULE,
  10390. + },
  10391. +};
  10392. +
  10393. +static int __init nxp_74hc153_init(void)
  10394. +{
  10395. + return platform_driver_register(&nxp_74hc153_driver);
  10396. +}
  10397. +subsys_initcall(nxp_74hc153_init);
  10398. +
  10399. +static void __exit nxp_74hc153_exit(void)
  10400. +{
  10401. + platform_driver_unregister(&nxp_74hc153_driver);
  10402. +}
  10403. +module_exit(nxp_74hc153_exit);
  10404. +
  10405. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10406. +MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153");
  10407. +MODULE_LICENSE("GPL v2");
  10408. +MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME);
  10409. diff -Nur linux-2.6.36.orig/drivers/input/misc/Kconfig linux-2.6.36/drivers/input/misc/Kconfig
  10410. --- linux-2.6.36.orig/drivers/input/misc/Kconfig 2010-10-20 22:30:22.000000000 +0200
  10411. +++ linux-2.6.36/drivers/input/misc/Kconfig 2010-12-17 18:34:51.000000000 +0100
  10412. @@ -438,4 +438,20 @@
  10413. To compile this driver as a module, choose M here: the
  10414. module will be called adxl34x-spi.
  10415. +config INPUT_GPIO_BUTTONS
  10416. + tristate "Polled GPIO buttons interface"
  10417. + depends on GENERIC_GPIO
  10418. + select INPUT_POLLDEV
  10419. + help
  10420. + This driver implements support for buttons connected
  10421. + to GPIO pins of various CPUs (and some other chips).
  10422. +
  10423. + Say Y here if your device has buttons connected
  10424. + directly to such GPIO pins. Your board-specific
  10425. + setup logic must also provide a platform device,
  10426. + with configuration data saying which GPIOs are used.
  10427. +
  10428. + To compile this driver as a module, choose M here: the
  10429. + module will be called gpio-buttons.
  10430. +
  10431. endif
  10432. diff -Nur linux-2.6.36.orig/drivers/input/misc/Makefile linux-2.6.36/drivers/input/misc/Makefile
  10433. --- linux-2.6.36.orig/drivers/input/misc/Makefile 2010-10-20 22:30:22.000000000 +0200
  10434. +++ linux-2.6.36/drivers/input/misc/Makefile 2010-12-17 18:34:51.000000000 +0100
  10435. @@ -41,4 +41,5 @@
  10436. obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
  10437. obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
  10438. obj-$(CONFIG_INPUT_YEALINK) += yealink.o
  10439. +obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o
  10440. diff -Nur linux-2.6.36.orig/drivers/input/misc/gpio_buttons.c linux-2.6.36/drivers/input/misc/gpio_buttons.c
  10441. --- linux-2.6.36.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100
  10442. +++ linux-2.6.36/drivers/input/misc/gpio_buttons.c 2010-12-17 18:34:51.000000000 +0100
  10443. @@ -0,0 +1,216 @@
  10444. +/*
  10445. + * Driver for buttons on GPIO lines not capable of generating interrupts
  10446. + *
  10447. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  10448. + * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
  10449. + *
  10450. + * This file was based on: /drivers/input/misc/cobalt_btns.c
  10451. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  10452. + *
  10453. + * also was based on: /drivers/input/keyboard/gpio_keys.c
  10454. + * Copyright 2005 Phil Blundell
  10455. + *
  10456. + * This program is free software; you can redistribute it and/or modify
  10457. + * it under the terms of the GNU General Public License version 2 as
  10458. + * published by the Free Software Foundation.
  10459. + *
  10460. + */
  10461. +
  10462. +#include <linux/kernel.h>
  10463. +#include <linux/module.h>
  10464. +#include <linux/init.h>
  10465. +#include <linux/slab.h>
  10466. +
  10467. +#include <linux/input.h>
  10468. +#include <linux/input-polldev.h>
  10469. +#include <linux/ioport.h>
  10470. +#include <linux/platform_device.h>
  10471. +
  10472. +#include <linux/gpio_buttons.h>
  10473. +
  10474. +#include <asm/gpio.h>
  10475. +
  10476. +#define DRV_NAME "gpio-buttons"
  10477. +#define DRV_VERSION "0.1.2"
  10478. +#define PFX DRV_NAME ": "
  10479. +
  10480. +struct gpio_button_data {
  10481. + int last_state;
  10482. + int count;
  10483. +};
  10484. +
  10485. +struct gpio_buttons_dev {
  10486. + struct input_polled_dev *poll_dev;
  10487. + struct gpio_buttons_platform_data *pdata;
  10488. + struct gpio_button_data *data;
  10489. +};
  10490. +
  10491. +static void gpio_buttons_poll(struct input_polled_dev *dev)
  10492. +{
  10493. + struct gpio_buttons_dev *bdev = dev->private;
  10494. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10495. + struct input_dev *input = dev->input;
  10496. + int i;
  10497. +
  10498. + for (i = 0; i < bdev->pdata->nbuttons; i++) {
  10499. + struct gpio_button *button = &pdata->buttons[i];
  10500. + unsigned int type = button->type ?: EV_KEY;
  10501. + int state;
  10502. +
  10503. + if (bdev->data[i].count < button->threshold) {
  10504. + bdev->data[i].count++;
  10505. + continue;
  10506. + }
  10507. +
  10508. + state = gpio_get_value(button->gpio) ? 1 : 0;
  10509. + if (state != bdev->data[i].last_state) {
  10510. + input_event(input, type, button->code,
  10511. + !!(state ^ button->active_low));
  10512. + input_sync(input);
  10513. + bdev->data[i].count = 0;
  10514. + bdev->data[i].last_state = state;
  10515. + }
  10516. + }
  10517. +}
  10518. +
  10519. +static int __devinit gpio_buttons_probe(struct platform_device *pdev)
  10520. +{
  10521. + struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data;
  10522. + struct gpio_buttons_dev *bdev;
  10523. + struct input_polled_dev *poll_dev;
  10524. + struct input_dev *input;
  10525. + int error, i;
  10526. +
  10527. + if (!pdata)
  10528. + return -ENXIO;
  10529. +
  10530. + bdev = kzalloc(sizeof(struct gpio_buttons_dev) +
  10531. + sizeof(struct gpio_button_data) * pdata->nbuttons,
  10532. + GFP_KERNEL);
  10533. + if (!bdev) {
  10534. + printk(KERN_ERR DRV_NAME "no memory for device\n");
  10535. + return -ENOMEM;
  10536. + }
  10537. +
  10538. + bdev->data = (struct gpio_button_data *) &bdev[1];
  10539. +
  10540. + poll_dev = input_allocate_polled_device();
  10541. + if (!poll_dev) {
  10542. + printk(KERN_ERR DRV_NAME "no memory for polled device\n");
  10543. + error = -ENOMEM;
  10544. + goto err_free_bdev;
  10545. + }
  10546. +
  10547. + poll_dev->private = bdev;
  10548. + poll_dev->poll = gpio_buttons_poll;
  10549. + poll_dev->poll_interval = pdata->poll_interval;
  10550. +
  10551. + input = poll_dev->input;
  10552. +
  10553. + input->evbit[0] = BIT(EV_KEY);
  10554. + input->name = pdev->name;
  10555. + input->phys = "gpio-buttons/input0";
  10556. + input->dev.parent = &pdev->dev;
  10557. +
  10558. + input->id.bustype = BUS_HOST;
  10559. + input->id.vendor = 0x0001;
  10560. + input->id.product = 0x0001;
  10561. + input->id.version = 0x0100;
  10562. +
  10563. + for (i = 0; i < pdata->nbuttons; i++) {
  10564. + struct gpio_button *button = &pdata->buttons[i];
  10565. + unsigned int gpio = button->gpio;
  10566. + unsigned int type = button->type ?: EV_KEY;
  10567. +
  10568. + error = gpio_request(gpio, button->desc ?
  10569. + button->desc : DRV_NAME);
  10570. + if (error) {
  10571. + printk(KERN_ERR PFX "unable to claim gpio %u, "
  10572. + "error %d\n", gpio, error);
  10573. + goto err_free_gpio;
  10574. + }
  10575. +
  10576. + error = gpio_direction_input(gpio);
  10577. + if (error) {
  10578. + printk(KERN_ERR PFX "unable to set direction on "
  10579. + "gpio %u, error %d\n", gpio, error);
  10580. + goto err_free_gpio;
  10581. + }
  10582. +
  10583. + input_set_capability(input, type, button->code);
  10584. + bdev->data[i].last_state = gpio_get_value(button->gpio) ? 1 : 0;
  10585. + }
  10586. +
  10587. + bdev->poll_dev = poll_dev;
  10588. + bdev->pdata = pdata;
  10589. + platform_set_drvdata(pdev, bdev);
  10590. +
  10591. + error = input_register_polled_device(poll_dev);
  10592. + if (error) {
  10593. + printk(KERN_ERR PFX "unable to register polled device, "
  10594. + "error %d\n", error);
  10595. + goto err_free_gpio;
  10596. + }
  10597. +
  10598. + return 0;
  10599. +
  10600. +err_free_gpio:
  10601. + for (i = i - 1; i >= 0; i--)
  10602. + gpio_free(pdata->buttons[i].gpio);
  10603. +
  10604. + input_free_polled_device(poll_dev);
  10605. +
  10606. +err_free_bdev:
  10607. + kfree(bdev);
  10608. +
  10609. + platform_set_drvdata(pdev, NULL);
  10610. + return error;
  10611. +}
  10612. +
  10613. +static int __devexit gpio_buttons_remove(struct platform_device *pdev)
  10614. +{
  10615. + struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev);
  10616. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10617. + int i;
  10618. +
  10619. + input_unregister_polled_device(bdev->poll_dev);
  10620. +
  10621. + for (i = 0; i < pdata->nbuttons; i++)
  10622. + gpio_free(pdata->buttons[i].gpio);
  10623. +
  10624. + input_free_polled_device(bdev->poll_dev);
  10625. +
  10626. + kfree(bdev);
  10627. + platform_set_drvdata(pdev, NULL);
  10628. +
  10629. + return 0;
  10630. +}
  10631. +
  10632. +static struct platform_driver gpio_buttons_driver = {
  10633. + .probe = gpio_buttons_probe,
  10634. + .remove = __devexit_p(gpio_buttons_remove),
  10635. + .driver = {
  10636. + .name = DRV_NAME,
  10637. + .owner = THIS_MODULE,
  10638. + },
  10639. +};
  10640. +
  10641. +static int __init gpio_buttons_init(void)
  10642. +{
  10643. + printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n");
  10644. + return platform_driver_register(&gpio_buttons_driver);
  10645. +}
  10646. +
  10647. +static void __exit gpio_buttons_exit(void)
  10648. +{
  10649. + platform_driver_unregister(&gpio_buttons_driver);
  10650. +}
  10651. +
  10652. +module_init(gpio_buttons_init);
  10653. +module_exit(gpio_buttons_exit);
  10654. +
  10655. +MODULE_LICENSE("GPL");
  10656. +MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
  10657. +MODULE_VERSION(DRV_VERSION);
  10658. +MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs");
  10659. +
  10660. diff -Nur linux-2.6.36.orig/drivers/leds/leds-rb750.c linux-2.6.36/drivers/leds/leds-rb750.c
  10661. --- linux-2.6.36.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100
  10662. +++ linux-2.6.36/drivers/leds/leds-rb750.c 2010-12-17 18:34:51.000000000 +0100
  10663. @@ -0,0 +1,140 @@
  10664. +/*
  10665. + * LED driver for the RouterBOARD 750
  10666. + *
  10667. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  10668. + *
  10669. + * This program is free software; you can redistribute it and/or modify
  10670. + * it under the terms of the GNU General Public License version 2 as
  10671. + * published by the Free Software Foundation.
  10672. + *
  10673. + */
  10674. +#include <linux/kernel.h>
  10675. +#include <linux/init.h>
  10676. +#include <linux/platform_device.h>
  10677. +#include <linux/leds.h>
  10678. +
  10679. +#include <asm/mach-ar71xx/mach-rb750.h>
  10680. +
  10681. +#define DRV_NAME "leds-rb750"
  10682. +
  10683. +struct rb750_led_dev {
  10684. + struct led_classdev cdev;
  10685. + u32 mask;
  10686. + int active_low;
  10687. +};
  10688. +
  10689. +struct rb750_led_drvdata {
  10690. + struct rb750_led_dev *led_devs;
  10691. + int num_leds;
  10692. +};
  10693. +
  10694. +static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev)
  10695. +{
  10696. + return (struct rb750_led_dev *)container_of(led_cdev,
  10697. + struct rb750_led_dev, cdev);
  10698. +}
  10699. +
  10700. +static void rb750_led_brightness_set(struct led_classdev *led_cdev,
  10701. + enum led_brightness value)
  10702. +{
  10703. + struct rb750_led_dev *rbled = to_rbled(led_cdev);
  10704. + int level;
  10705. +
  10706. + level = (value == LED_OFF) ? 0 : 1;
  10707. + level ^= rbled->active_low;
  10708. +
  10709. + if (level)
  10710. + rb750_latch_change(0, rbled->mask);
  10711. + else
  10712. + rb750_latch_change(rbled->mask, 0);
  10713. +}
  10714. +
  10715. +static int __devinit rb750_led_probe(struct platform_device *pdev)
  10716. +{
  10717. + struct rb750_led_platform_data *pdata;
  10718. + struct rb750_led_drvdata *drvdata;
  10719. + int ret = 0;
  10720. + int i;
  10721. +
  10722. + pdata = pdev->dev.platform_data;
  10723. + if (!pdata)
  10724. + return -EINVAL;
  10725. +
  10726. + drvdata = kzalloc(sizeof(struct rb750_led_drvdata) +
  10727. + sizeof(struct rb750_led_dev) * pdata->num_leds,
  10728. + GFP_KERNEL);
  10729. + if (!drvdata)
  10730. + return -ENOMEM;
  10731. +
  10732. + drvdata->num_leds = pdata->num_leds;
  10733. + drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1];
  10734. +
  10735. + for (i = 0; i < drvdata->num_leds; i++) {
  10736. + struct rb750_led_dev *rbled = &drvdata->led_devs[i];
  10737. + struct rb750_led_data *led_data = &pdata->leds[i];
  10738. +
  10739. + rbled->cdev.name = led_data->name;
  10740. + rbled->cdev.default_trigger = led_data->default_trigger;
  10741. + rbled->cdev.brightness_set = rb750_led_brightness_set;
  10742. + rbled->cdev.brightness = LED_OFF;
  10743. +
  10744. + rbled->mask = led_data->mask;
  10745. + rbled->active_low = !!led_data->active_low;
  10746. +
  10747. + ret = led_classdev_register(&pdev->dev, &rbled->cdev);
  10748. + if (ret)
  10749. + goto err;
  10750. + }
  10751. +
  10752. + platform_set_drvdata(pdev, drvdata);
  10753. + return 0;
  10754. +
  10755. + err:
  10756. + for (i = i - 1; i >= 0; i--)
  10757. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10758. +
  10759. + kfree(drvdata);
  10760. + return ret;
  10761. +}
  10762. +
  10763. +static int __devexit rb750_led_remove(struct platform_device *pdev)
  10764. +{
  10765. + struct rb750_led_drvdata *drvdata;
  10766. + int i;
  10767. +
  10768. + drvdata = platform_get_drvdata(pdev);
  10769. + for (i = 0; i < drvdata->num_leds; i++)
  10770. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10771. +
  10772. + kfree(drvdata);
  10773. + return 0;
  10774. +}
  10775. +
  10776. +static struct platform_driver rb750_led_driver = {
  10777. + .probe = rb750_led_probe,
  10778. + .remove = __devexit_p(rb750_led_remove),
  10779. + .driver = {
  10780. + .name = DRV_NAME,
  10781. + .owner = THIS_MODULE,
  10782. + },
  10783. +};
  10784. +
  10785. +MODULE_ALIAS("platform:leds-rb750");
  10786. +
  10787. +static int __init rb750_led_init(void)
  10788. +{
  10789. + return platform_driver_register(&rb750_led_driver);
  10790. +}
  10791. +
  10792. +static void __exit rb750_led_exit(void)
  10793. +{
  10794. + platform_driver_unregister(&rb750_led_driver);
  10795. +}
  10796. +
  10797. +module_init(rb750_led_init);
  10798. +module_exit(rb750_led_exit);
  10799. +
  10800. +MODULE_DESCRIPTION(DRV_NAME);
  10801. +MODULE_DESCRIPTION("LED driver for the RouterBOARD 750");
  10802. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10803. +MODULE_LICENSE("GPL v2");
  10804. diff -Nur linux-2.6.36.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.36/drivers/leds/leds-wndr3700-usb.c
  10805. --- linux-2.6.36.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100
  10806. +++ linux-2.6.36/drivers/leds/leds-wndr3700-usb.c 2010-12-17 18:34:51.000000000 +0100
  10807. @@ -0,0 +1,75 @@
  10808. +/*
  10809. + * USB LED driver for the NETGEAR WNDR3700
  10810. + *
  10811. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10812. + *
  10813. + * This program is free software; you can redistribute it and/or modify it
  10814. + * under the terms of the GNU General Public License version 2 as published
  10815. + * by the Free Software Foundation.
  10816. + */
  10817. +
  10818. +#include <linux/leds.h>
  10819. +#include <linux/module.h>
  10820. +#include <linux/platform_device.h>
  10821. +
  10822. +#include <asm/mach-ar71xx/ar71xx.h>
  10823. +
  10824. +#define DRIVER_NAME "wndr3700-led-usb"
  10825. +
  10826. +static void wndr3700_usb_led_set(struct led_classdev *cdev,
  10827. + enum led_brightness brightness)
  10828. +{
  10829. + if (brightness)
  10830. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  10831. + else
  10832. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  10833. +}
  10834. +
  10835. +static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev)
  10836. +{
  10837. + return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL;
  10838. +}
  10839. +
  10840. +static struct led_classdev wndr3700_usb_led = {
  10841. + .name = "wndr3700:green:usb",
  10842. + .brightness_set = wndr3700_usb_led_set,
  10843. + .brightness_get = wndr3700_usb_led_get,
  10844. +};
  10845. +
  10846. +static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev)
  10847. +{
  10848. + return led_classdev_register(&pdev->dev, &wndr3700_usb_led);
  10849. +}
  10850. +
  10851. +static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev)
  10852. +{
  10853. + led_classdev_unregister(&wndr3700_usb_led);
  10854. + return 0;
  10855. +}
  10856. +
  10857. +static struct platform_driver wndr3700_usb_led_driver = {
  10858. + .probe = wndr3700_usb_led_probe,
  10859. + .remove = __devexit_p(wndr3700_usb_led_remove),
  10860. + .driver = {
  10861. + .name = DRIVER_NAME,
  10862. + .owner = THIS_MODULE,
  10863. + },
  10864. +};
  10865. +
  10866. +static int __init wndr3700_usb_led_init(void)
  10867. +{
  10868. + return platform_driver_register(&wndr3700_usb_led_driver);
  10869. +}
  10870. +
  10871. +static void __exit wndr3700_usb_led_exit(void)
  10872. +{
  10873. + platform_driver_unregister(&wndr3700_usb_led_driver);
  10874. +}
  10875. +
  10876. +module_init(wndr3700_usb_led_init);
  10877. +module_exit(wndr3700_usb_led_exit);
  10878. +
  10879. +MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700");
  10880. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10881. +MODULE_LICENSE("GPL v2");
  10882. +MODULE_ALIAS("platform:" DRIVER_NAME);
  10883. diff -Nur linux-2.6.36.orig/drivers/mtd/maps/Kconfig linux-2.6.36/drivers/mtd/maps/Kconfig
  10884. --- linux-2.6.36.orig/drivers/mtd/maps/Kconfig 2010-10-20 22:30:22.000000000 +0200
  10885. +++ linux-2.6.36/drivers/mtd/maps/Kconfig 2010-12-17 18:34:51.000000000 +0100
  10886. @@ -251,6 +251,13 @@
  10887. help
  10888. Support for flash chips on NETtel/SecureEdge/SnapGear boards.
  10889. +config MTD_AR91XX_FLASH
  10890. + tristate "Atheros AR91xx parallel flash support"
  10891. + depends on ATHEROS_AR71XX
  10892. + select MTD_COMPLEX_MAPPINGS
  10893. + help
  10894. + Parallel flash driver for the Atheros AR91xx based boards.
  10895. +
  10896. config MTD_DILNETPC
  10897. tristate "CFI Flash device mapped on DIL/Net PC"
  10898. depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
  10899. diff -Nur linux-2.6.36.orig/drivers/mtd/maps/Makefile linux-2.6.36/drivers/mtd/maps/Makefile
  10900. --- linux-2.6.36.orig/drivers/mtd/maps/Makefile 2010-10-20 22:30:22.000000000 +0200
  10901. +++ linux-2.6.36/drivers/mtd/maps/Makefile 2010-12-17 18:34:51.000000000 +0100
  10902. @@ -7,6 +7,7 @@
  10903. endif
  10904. # Chip mappings
  10905. +obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o
  10906. obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
  10907. obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
  10908. obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
  10909. diff -Nur linux-2.6.36.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.36/drivers/mtd/maps/ar91xx_flash.c
  10910. --- linux-2.6.36.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100
  10911. +++ linux-2.6.36/drivers/mtd/maps/ar91xx_flash.c 2010-12-17 18:34:51.000000000 +0100
  10912. @@ -0,0 +1,310 @@
  10913. +/*
  10914. + * Parallel flash driver for the Atheros AR91xx SoC
  10915. + *
  10916. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10917. + *
  10918. + * This program is free software; you can redistribute it and/or modify
  10919. + * it under the terms of the GNU General Public License version 2 as
  10920. + * published by the Free Software Foundation.
  10921. + *
  10922. + */
  10923. +
  10924. +#include <linux/module.h>
  10925. +#include <linux/types.h>
  10926. +#include <linux/kernel.h>
  10927. +#include <linux/init.h>
  10928. +#include <linux/slab.h>
  10929. +#include <linux/device.h>
  10930. +#include <linux/platform_device.h>
  10931. +#include <linux/mtd/mtd.h>
  10932. +#include <linux/mtd/map.h>
  10933. +#include <linux/mtd/partitions.h>
  10934. +#include <linux/io.h>
  10935. +
  10936. +#include <asm/mach-ar71xx/ar71xx.h>
  10937. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  10938. +
  10939. +#define DRV_NAME "ar91xx-flash"
  10940. +
  10941. +struct ar91xx_flash_info {
  10942. + struct mtd_info *mtd;
  10943. + struct map_info map;
  10944. +#ifdef CONFIG_MTD_PARTITIONS
  10945. + int nr_parts;
  10946. + struct mtd_partition *parts;
  10947. +#endif
  10948. +};
  10949. +
  10950. +static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs)
  10951. +{
  10952. + map_word val;
  10953. +
  10954. + if (map_bankwidth_is_1(map))
  10955. + val.x[0] = __raw_readb(map->virt + (ofs ^ 3));
  10956. + else if (map_bankwidth_is_2(map))
  10957. + val.x[0] = __raw_readw(map->virt + (ofs ^ 2));
  10958. + else
  10959. + val = map_word_ff(map);
  10960. +
  10961. + return val;
  10962. +}
  10963. +
  10964. +static void ar91xx_flash_write(struct map_info *map, map_word d,
  10965. + unsigned long ofs)
  10966. +{
  10967. + if (map_bankwidth_is_1(map))
  10968. + __raw_writeb(d.x[0], map->virt + (ofs ^ 3));
  10969. + else if (map_bankwidth_is_2(map))
  10970. + __raw_writew(d.x[0], map->virt + (ofs ^ 2));
  10971. +
  10972. + mb();
  10973. +}
  10974. +
  10975. +static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs)
  10976. +{
  10977. + map_word ret;
  10978. +
  10979. + ar71xx_flash_acquire();
  10980. + ret = ar91xx_flash_read(map, ofs);
  10981. + ar71xx_flash_release();
  10982. +
  10983. + return ret;
  10984. +}
  10985. +
  10986. +static void ar91xx_flash_write_lock(struct map_info *map, map_word d,
  10987. + unsigned long ofs)
  10988. +{
  10989. + ar71xx_flash_acquire();
  10990. + ar91xx_flash_write(map, d, ofs);
  10991. + ar71xx_flash_release();
  10992. +}
  10993. +
  10994. +static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to,
  10995. + unsigned long from, ssize_t len)
  10996. +{
  10997. + ar71xx_flash_acquire();
  10998. + inline_map_copy_from(map, to, from, len);
  10999. + ar71xx_flash_release();
  11000. +}
  11001. +
  11002. +static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to,
  11003. + const void *from, ssize_t len)
  11004. +{
  11005. + ar71xx_flash_acquire();
  11006. + inline_map_copy_to(map, to, from, len);
  11007. + ar71xx_flash_release();
  11008. +}
  11009. +
  11010. +static int ar91xx_flash_remove(struct platform_device *pdev)
  11011. +{
  11012. + struct ar91xx_flash_platform_data *pdata;
  11013. + struct ar91xx_flash_info *info;
  11014. +
  11015. + info = platform_get_drvdata(pdev);
  11016. + if (info == NULL)
  11017. + return 0;
  11018. +
  11019. + platform_set_drvdata(pdev, NULL);
  11020. +
  11021. + if (info->mtd == NULL)
  11022. + return 0;
  11023. +
  11024. + pdata = pdev->dev.platform_data;
  11025. +#ifdef CONFIG_MTD_PARTITIONS
  11026. + if (info->nr_parts) {
  11027. + del_mtd_partitions(info->mtd);
  11028. + kfree(info->parts);
  11029. + } else if (pdata->nr_parts) {
  11030. + del_mtd_partitions(info->mtd);
  11031. + } else {
  11032. + del_mtd_device(info->mtd);
  11033. + }
  11034. +#else
  11035. + del_mtd_device(info->mtd);
  11036. +#endif
  11037. + map_destroy(info->mtd);
  11038. +
  11039. + return 0;
  11040. +}
  11041. +
  11042. +static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
  11043. +#ifdef CONFIG_MTD_PARTITIONS
  11044. +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  11045. +#endif
  11046. +
  11047. +static int ar91xx_flash_probe(struct platform_device *pdev)
  11048. +{
  11049. + struct ar91xx_flash_platform_data *pdata;
  11050. + struct ar91xx_flash_info *info;
  11051. + struct resource *res;
  11052. + struct resource *region;
  11053. + const char **probe_type;
  11054. + int err = 0;
  11055. +
  11056. + pdata = pdev->dev.platform_data;
  11057. + if (pdata == NULL)
  11058. + return -EINVAL;
  11059. +
  11060. + info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info),
  11061. + GFP_KERNEL);
  11062. + if (info == NULL) {
  11063. + err = -ENOMEM;
  11064. + goto err_out;
  11065. + }
  11066. +
  11067. + platform_set_drvdata(pdev, info);
  11068. +
  11069. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  11070. + if (res == NULL) {
  11071. + err = -ENOENT;
  11072. + goto err_out;
  11073. + }
  11074. +
  11075. + dev_info(&pdev->dev, "%.8llx at %.8llx\n",
  11076. + (unsigned long long)(res->end - res->start + 1),
  11077. + (unsigned long long)res->start);
  11078. +
  11079. + region = devm_request_mem_region(&pdev->dev,
  11080. + res->start, res->end - res->start + 1,
  11081. + dev_name(&pdev->dev));
  11082. + if (region == NULL) {
  11083. + dev_err(&pdev->dev, "could not reserve memory region\n");
  11084. + err = -ENOMEM;
  11085. + goto err_out;
  11086. + }
  11087. +
  11088. + info->map.name = dev_name(&pdev->dev);
  11089. + info->map.phys = res->start;
  11090. + info->map.size = res->end - res->start + 1;
  11091. + info->map.bankwidth = pdata->width;
  11092. +
  11093. + info->map.virt = devm_ioremap(&pdev->dev, info->map.phys,
  11094. + info->map.size);
  11095. + if (info->map.virt == NULL) {
  11096. + dev_err(&pdev->dev, "failed to ioremap flash region\n");
  11097. + err = -EIO;
  11098. + goto err_out;
  11099. + }
  11100. +
  11101. + simple_map_init(&info->map);
  11102. + if (pdata->is_shared) {
  11103. + info->map.read = ar91xx_flash_read_lock;
  11104. + info->map.write = ar91xx_flash_write_lock;
  11105. + info->map.copy_from = ar91xx_flash_copy_from_lock;
  11106. + info->map.copy_to = ar91xx_flash_copy_to_lock;
  11107. + } else {
  11108. + info->map.read = ar91xx_flash_read;
  11109. + info->map.write = ar91xx_flash_write;
  11110. + }
  11111. +
  11112. + probe_type = rom_probe_types;
  11113. + for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
  11114. + info->mtd = do_map_probe(*probe_type, &info->map);
  11115. +
  11116. + if (info->mtd == NULL) {
  11117. + dev_err(&pdev->dev, "map_probe failed\n");
  11118. + err = -ENXIO;
  11119. + goto err_out;
  11120. + }
  11121. +
  11122. + info->mtd->owner = THIS_MODULE;
  11123. +
  11124. +#ifdef CONFIG_MTD_PARTITIONS
  11125. + if (pdata->nr_parts) {
  11126. + dev_info(&pdev->dev, "using static partition mapping\n");
  11127. + add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
  11128. + return 0;
  11129. + }
  11130. +
  11131. + err = parse_mtd_partitions(info->mtd, part_probe_types,
  11132. + &info->parts, 0);
  11133. + if (err > 0) {
  11134. + add_mtd_partitions(info->mtd, info->parts, err);
  11135. + return 0;
  11136. + }
  11137. +#endif
  11138. +
  11139. + add_mtd_device(info->mtd);
  11140. + return 0;
  11141. +
  11142. + err_out:
  11143. + ar91xx_flash_remove(pdev);
  11144. + return err;
  11145. +}
  11146. +
  11147. +#ifdef CONFIG_PM
  11148. +static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state)
  11149. +{
  11150. + struct ar91xx_flash_info *info = platform_get_drvdata(dev);
  11151. + int ret = 0;
  11152. +
  11153. + if (info->mtd->suspend)
  11154. + ret = info->mtd->suspend(info->mtd);
  11155. +
  11156. + if (ret)
  11157. + goto fail;
  11158. +
  11159. + return 0;
  11160. +
  11161. + fail:
  11162. + if (info->mtd->suspend) {
  11163. + BUG_ON(!info->mtd->resume);
  11164. + info->mtd->resume(info->mtd);
  11165. + }
  11166. +
  11167. + return ret;
  11168. +}
  11169. +
  11170. +static int ar91xx_flash_resume(struct platform_device *pdev)
  11171. +{
  11172. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  11173. +
  11174. + if (info->mtd->resume)
  11175. + info->mtd->resume(info->mtd);
  11176. +
  11177. + return 0;
  11178. +}
  11179. +
  11180. +static void ar91xx_flash_shutdown(struct platform_device *pdev)
  11181. +{
  11182. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  11183. +
  11184. + if (info->mtd->suspend && info->mtd->resume)
  11185. + if (info->mtd->suspend(info->mtd) == 0)
  11186. + info->mtd->resume(info->mtd);
  11187. +}
  11188. +#else
  11189. +#define ar91xx_flash_suspend NULL
  11190. +#define ar91xx_flash_resume NULL
  11191. +#define ar91xx_flash_shutdown NULL
  11192. +#endif
  11193. +
  11194. +static struct platform_driver ar91xx_flash_driver = {
  11195. + .probe = ar91xx_flash_probe,
  11196. + .remove = ar91xx_flash_remove,
  11197. + .suspend = ar91xx_flash_suspend,
  11198. + .resume = ar91xx_flash_resume,
  11199. + .shutdown = ar91xx_flash_shutdown,
  11200. + .driver = {
  11201. + .name = DRV_NAME,
  11202. + .owner = THIS_MODULE,
  11203. + },
  11204. +};
  11205. +
  11206. +static int __init ar91xx_flash_init(void)
  11207. +{
  11208. + return platform_driver_register(&ar91xx_flash_driver);
  11209. +}
  11210. +
  11211. +static void __exit ar91xx_flash_exit(void)
  11212. +{
  11213. + platform_driver_unregister(&ar91xx_flash_driver);
  11214. +}
  11215. +
  11216. +module_init(ar91xx_flash_init);
  11217. +module_exit(ar91xx_flash_exit);
  11218. +
  11219. +MODULE_LICENSE("GPL v2");
  11220. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11221. +MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC");
  11222. +MODULE_ALIAS("platform:" DRV_NAME);
  11223. diff -Nur linux-2.6.36.orig/drivers/mtd/nand/Kconfig linux-2.6.36/drivers/mtd/nand/Kconfig
  11224. --- linux-2.6.36.orig/drivers/mtd/nand/Kconfig 2010-10-20 22:30:22.000000000 +0200
  11225. +++ linux-2.6.36/drivers/mtd/nand/Kconfig 2010-12-17 18:34:51.000000000 +0100
  11226. @@ -531,4 +531,8 @@
  11227. help
  11228. Enables support for NAND Flash on JZ4740 SoC based boards.
  11229. +config MTD_NAND_RB4XX
  11230. + tristate "NAND flash driver for RouterBoard 4xx series"
  11231. + depends on MTD_NAND && AR71XX_MACH_RB4XX
  11232. +
  11233. endif # MTD_NAND
  11234. diff -Nur linux-2.6.36.orig/drivers/mtd/nand/Makefile linux-2.6.36/drivers/mtd/nand/Makefile
  11235. --- linux-2.6.36.orig/drivers/mtd/nand/Makefile 2010-10-20 22:30:22.000000000 +0200
  11236. +++ linux-2.6.36/drivers/mtd/nand/Makefile 2010-12-17 18:34:51.000000000 +0100
  11237. @@ -32,6 +32,7 @@
  11238. obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
  11239. obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
  11240. obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
  11241. +obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
  11242. obj-$(CONFIG_MTD_ALAUDA) += alauda.o
  11243. obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
  11244. obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
  11245. diff -Nur linux-2.6.36.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.36/drivers/mtd/nand/rb4xx_nand.c
  11246. --- linux-2.6.36.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100
  11247. +++ linux-2.6.36/drivers/mtd/nand/rb4xx_nand.c 2010-12-17 18:34:51.000000000 +0100
  11248. @@ -0,0 +1,513 @@
  11249. +/*
  11250. + * NAND flash driver for the MikroTik RouterBoard 4xx series
  11251. + *
  11252. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  11253. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  11254. + *
  11255. + * This file was based on the driver for Linux 2.6.22 published by
  11256. + * MikroTik for their RouterBoard 4xx series devices.
  11257. + *
  11258. + * This program is free software; you can redistribute it and/or modify it
  11259. + * under the terms of the GNU General Public License version 2 as published
  11260. + * by the Free Software Foundation.
  11261. + */
  11262. +
  11263. +#include <linux/init.h>
  11264. +#include <linux/mtd/nand.h>
  11265. +#include <linux/mtd/mtd.h>
  11266. +#include <linux/mtd/partitions.h>
  11267. +#include <linux/platform_device.h>
  11268. +#include <linux/delay.h>
  11269. +#include <linux/io.h>
  11270. +#include <linux/gpio.h>
  11271. +#include <linux/slab.h>
  11272. +
  11273. +#include <asm/mach-ar71xx/ar71xx.h>
  11274. +
  11275. +#define DRV_NAME "rb4xx-nand"
  11276. +#define DRV_VERSION "0.1.10"
  11277. +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
  11278. +
  11279. +#define USE_FAST_READ 1
  11280. +#define USE_FAST_WRITE 1
  11281. +#undef RB4XX_NAND_DEBUG
  11282. +
  11283. +#ifdef RB4XX_NAND_DEBUG
  11284. +#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg)
  11285. +#else
  11286. +#define DBG(fmt, arg...) do {} while (0)
  11287. +#endif
  11288. +
  11289. +#define RB4XX_NAND_GPIO_RDY 5
  11290. +#define RB4XX_FLASH_HZ 33333334
  11291. +#define RB4XX_NAND_HZ 33333334
  11292. +
  11293. +#define SPI_CTRL_FASTEST 0x40
  11294. +#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */
  11295. +#define SBIT_IOC_BASE SPI_IOC_CS1
  11296. +#define SBIT_IOC_DO_SHIFT 0
  11297. +#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT)
  11298. +#define SBIT_IOC_DO2_SHIFT 18
  11299. +#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT)
  11300. +
  11301. +#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */
  11302. +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */
  11303. +#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */
  11304. +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */
  11305. +
  11306. +#define CFG_BIT_nCE 0x80
  11307. +#define CFG_BIT_CLE 0x40
  11308. +#define CFG_BIT_ALE 0x20
  11309. +#define CFG_BIT_FAN 0x10
  11310. +#define CFG_BIT_nLED4 0x08
  11311. +#define CFG_BIT_nLED3 0x04
  11312. +#define CFG_BIT_nLED2 0x02
  11313. +#define CFG_BIT_nLED1 0x01
  11314. +
  11315. +#define CFG_BIT_nLEDS \
  11316. + (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4)
  11317. +
  11318. +struct rb4xx_nand_info {
  11319. + struct nand_chip chip;
  11320. + struct mtd_info mtd;
  11321. +};
  11322. +
  11323. +/*
  11324. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11325. + * will not be able to find the kernel that we load.
  11326. + */
  11327. +static struct nand_ecclayout rb4xx_nand_ecclayout = {
  11328. + .eccbytes = 6,
  11329. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11330. + .oobavail = 9,
  11331. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11332. +};
  11333. +
  11334. +static struct mtd_partition rb4xx_nand_partitions[] = {
  11335. + {
  11336. + .name = "booter",
  11337. + .offset = 0,
  11338. + .size = (256 * 1024),
  11339. + .mask_flags = MTD_WRITEABLE,
  11340. + },
  11341. + {
  11342. + .name = "kernel",
  11343. + .offset = (256 * 1024),
  11344. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11345. + },
  11346. + {
  11347. + .name = "rootfs",
  11348. + .offset = MTDPART_OFS_NXTBLK,
  11349. + .size = (1024*1024*64) - (1024*256) - (4 * 1024 * 1024)
  11350. + },
  11351. + {
  11352. + .name = "cfgfs",
  11353. + .offset = (1024*1024*64) - (1024*256),
  11354. + .size = (1024*256),
  11355. + },
  11356. +};
  11357. +
  11358. +#if USE_FAST_READ
  11359. +#define SPI_NDATA_BASE 0x00800000
  11360. +static unsigned spi_ctrl_fread = SPI_CTRL_SAFE;
  11361. +static unsigned spi_ctrl_flash = SPI_CTRL_SAFE;
  11362. +extern unsigned mips_hpt_frequency;
  11363. +#endif
  11364. +
  11365. +static inline unsigned rb4xx_spi_rreg(unsigned r)
  11366. +{
  11367. + return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11368. +}
  11369. +
  11370. +static inline void rb4xx_spi_wreg(unsigned r, unsigned v)
  11371. +{
  11372. + __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11373. +}
  11374. +
  11375. +static inline void do_spi_clk(int bit)
  11376. +{
  11377. + unsigned bval = SBIT_IOC_BASE | (bit & 1);
  11378. +
  11379. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11380. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11381. +}
  11382. +
  11383. +static void do_spi_byte(uint8_t byte)
  11384. +{
  11385. + do_spi_clk(byte >> 7);
  11386. + do_spi_clk(byte >> 6);
  11387. + do_spi_clk(byte >> 5);
  11388. + do_spi_clk(byte >> 4);
  11389. + do_spi_clk(byte >> 3);
  11390. + do_spi_clk(byte >> 2);
  11391. + do_spi_clk(byte >> 1);
  11392. + do_spi_clk(byte);
  11393. +
  11394. + DBG("spi_byte sent 0x%02x got 0x%x\n",
  11395. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11396. +}
  11397. +
  11398. +#if USE_FAST_WRITE
  11399. +static inline void do_spi_clk_fast(int bit1, int bit2)
  11400. +{
  11401. + unsigned bval = (SBIT_IOC_BASE |
  11402. + ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) |
  11403. + ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2));
  11404. +
  11405. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11406. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11407. +}
  11408. +
  11409. +static inline void do_spi_byte_fast(uint8_t byte)
  11410. +{
  11411. + do_spi_clk_fast(byte >> 7, byte >> 6);
  11412. + do_spi_clk_fast(byte >> 5, byte >> 4);
  11413. + do_spi_clk_fast(byte >> 3, byte >> 2);
  11414. + do_spi_clk_fast(byte >> 1, byte >> 0);
  11415. +
  11416. + DBG("spi_byte_fast sent 0x%02x got 0x%x\n",
  11417. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11418. +}
  11419. +#else
  11420. +static inline void do_spi_byte_fast(uint8_t byte)
  11421. +{
  11422. + do_spi_byte(byte);
  11423. +}
  11424. +#endif /* USE_FAST_WRITE */
  11425. +
  11426. +static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData,
  11427. + unsigned recvCnt, uint8_t *recvData,
  11428. + const uint8_t *verifyData, int fastWrite)
  11429. +{
  11430. + unsigned i;
  11431. +
  11432. + DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt);
  11433. +
  11434. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11435. + rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST);
  11436. +
  11437. + do_spi_byte(cmd);
  11438. +#if 0
  11439. + if (cmd == CPLD_CMD_READ_FAST) {
  11440. + do_spi_byte(0x80);
  11441. + do_spi_byte(0);
  11442. + do_spi_byte(0);
  11443. + }
  11444. +#endif
  11445. + for (i = 0; i < sendCnt; ++i) {
  11446. + if (fastWrite)
  11447. + do_spi_byte_fast(sendData[i]);
  11448. + else
  11449. + do_spi_byte(sendData[i]);
  11450. + }
  11451. +
  11452. + for (i = 0; i < recvCnt; ++i) {
  11453. + if (fastWrite)
  11454. + do_spi_byte_fast(0);
  11455. + else
  11456. + do_spi_byte(0);
  11457. +
  11458. + if (recvData) {
  11459. + recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff;
  11460. + } else if (verifyData) {
  11461. + if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS)
  11462. + & 0xff))
  11463. + break;
  11464. + }
  11465. + }
  11466. +
  11467. + rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0);
  11468. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash);
  11469. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11470. +
  11471. + return i == recvCnt;
  11472. +}
  11473. +
  11474. +static int got_write = 1;
  11475. +
  11476. +static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt)
  11477. +{
  11478. + do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1);
  11479. + got_write = 1;
  11480. +}
  11481. +
  11482. +static void rb4xx_nand_write_byte(uint8_t byte)
  11483. +{
  11484. + rb4xx_nand_write_data(&byte, 1);
  11485. +}
  11486. +
  11487. +#if USE_FAST_READ
  11488. +static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt)
  11489. +{
  11490. + static unsigned nboffset = 0x100000;
  11491. + unsigned addr;
  11492. +
  11493. + if (got_write) {
  11494. + nboffset = (nboffset + 31) & ~31;
  11495. + if (nboffset >= 0x100000) /* 1MB */
  11496. + nboffset = 0;
  11497. +
  11498. + got_write = 0;
  11499. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11500. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread);
  11501. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11502. + }
  11503. +
  11504. + addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset;
  11505. + DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt);
  11506. +
  11507. + nboffset += cnt;
  11508. + return (uint8_t *)addr;
  11509. +}
  11510. +
  11511. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11512. +{
  11513. + unsigned size32 = cnt & ~31;
  11514. + unsigned remain = cnt & 31;
  11515. +
  11516. + if (size32) {
  11517. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11518. + memcpy(buf, (void *)addr, size32);
  11519. + }
  11520. +
  11521. + if (remain) {
  11522. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11523. + buf + size32, NULL, 0);
  11524. + }
  11525. +}
  11526. +
  11527. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11528. +{
  11529. + unsigned size32 = cnt & ~31;
  11530. + unsigned remain = cnt & 31;
  11531. +
  11532. + if (size32) {
  11533. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11534. + if (memcmp(buf, (void *)addr, size32) != 0)
  11535. + return 0;
  11536. + }
  11537. +
  11538. + if (remain) {
  11539. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11540. + NULL, buf + size32, 0);
  11541. + }
  11542. + return 1;
  11543. +}
  11544. +#else /* USE_FAST_READ */
  11545. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11546. +{
  11547. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0);
  11548. +}
  11549. +
  11550. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11551. +{
  11552. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0);
  11553. +}
  11554. +#endif /* USE_FAST_READ */
  11555. +
  11556. +static void rb4xx_nand_write_cfg(uint8_t byte)
  11557. +{
  11558. + do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0);
  11559. + got_write = 1;
  11560. +}
  11561. +
  11562. +static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
  11563. +{
  11564. + return gpio_get_value(RB4XX_NAND_GPIO_RDY);
  11565. +}
  11566. +
  11567. +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11568. + unsigned int ctrl)
  11569. +{
  11570. + if (ctrl & NAND_CTRL_CHANGE) {
  11571. + uint8_t cfg = CFG_BIT_nLEDS;
  11572. +
  11573. + cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0;
  11574. + cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0;
  11575. + cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE;
  11576. +
  11577. + rb4xx_nand_write_cfg(cfg);
  11578. + }
  11579. +
  11580. + if (cmd != NAND_CMD_NONE)
  11581. + rb4xx_nand_write_byte(cmd);
  11582. +}
  11583. +
  11584. +static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd)
  11585. +{
  11586. + uint8_t byte = 0;
  11587. +
  11588. + rb4xx_nand_read_data(&byte, 1);
  11589. + return byte;
  11590. +}
  11591. +
  11592. +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
  11593. + int len)
  11594. +{
  11595. + rb4xx_nand_write_data(buf, len);
  11596. +}
  11597. +
  11598. +static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf,
  11599. + int len)
  11600. +{
  11601. + rb4xx_nand_read_data(buf, len);
  11602. +}
  11603. +
  11604. +static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
  11605. + int len)
  11606. +{
  11607. + if (!rb4xx_nand_verify_data(buf, len))
  11608. + return -EFAULT;
  11609. +
  11610. + return 0;
  11611. +}
  11612. +
  11613. +static unsigned get_spi_ctrl(unsigned hz_max, const char *name)
  11614. +{
  11615. + unsigned div;
  11616. +
  11617. + div = (ar71xx_ahb_freq - 1) / (2 * hz_max);
  11618. + /*
  11619. + * CPU has a bug at (div == 0) - first bit read is random
  11620. + */
  11621. + if (div == 0)
  11622. + ++div;
  11623. +
  11624. + if (name) {
  11625. + unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000;
  11626. + unsigned div_real = 2 * (div + 1);
  11627. + printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n",
  11628. + name,
  11629. + ahb_khz / div_real,
  11630. + ahb_khz, div_real);
  11631. + }
  11632. +
  11633. + return SPI_CTRL_FASTEST + div;
  11634. +}
  11635. +
  11636. +static int __init rb4xx_nand_probe(struct platform_device *pdev)
  11637. +{
  11638. + struct rb4xx_nand_info *info;
  11639. + int ret;
  11640. +
  11641. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  11642. +
  11643. + ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY");
  11644. + if (ret) {
  11645. + printk(KERN_ERR "rb4xx-nand: gpio request failed\n");
  11646. + return ret;
  11647. + }
  11648. +
  11649. + ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY);
  11650. + if (ret) {
  11651. + printk(KERN_ERR "rb4xx-nand: unable to set input mode "
  11652. + "on gpio%d\n", RB4XX_NAND_GPIO_RDY);
  11653. + goto err_free_gpio;
  11654. + }
  11655. +
  11656. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  11657. + if (!info) {
  11658. + printk(KERN_ERR "rb4xx-nand: no memory for private data\n");
  11659. + ret = -ENOMEM;
  11660. + goto err_free_gpio;
  11661. + }
  11662. +
  11663. +#if USE_FAST_READ
  11664. + spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND");
  11665. +#endif
  11666. + spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH");
  11667. +
  11668. + rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE);
  11669. +
  11670. + info->chip.priv = &info;
  11671. + info->mtd.priv = &info->chip;
  11672. + info->mtd.owner = THIS_MODULE;
  11673. +
  11674. + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
  11675. + info->chip.dev_ready = rb4xx_nand_dev_ready;
  11676. + info->chip.read_byte = rb4xx_nand_read_byte;
  11677. + info->chip.write_buf = rb4xx_nand_write_buf;
  11678. + info->chip.read_buf = rb4xx_nand_read_buf;
  11679. + info->chip.verify_buf = rb4xx_nand_verify_buf;
  11680. +
  11681. + info->chip.chip_delay = 25;
  11682. + info->chip.ecc.mode = NAND_ECC_SOFT;
  11683. + info->chip.options |= NAND_NO_AUTOINCR;
  11684. +
  11685. + platform_set_drvdata(pdev, info);
  11686. +
  11687. + ret = nand_scan_ident(&info->mtd, 1, NULL);
  11688. + if (ret) {
  11689. + ret = -ENXIO;
  11690. + goto err_free_info;
  11691. + }
  11692. +
  11693. + if (info->mtd.writesize == 512)
  11694. + info->chip.ecc.layout = &rb4xx_nand_ecclayout;
  11695. +
  11696. + ret = nand_scan_tail(&info->mtd);
  11697. + if (ret) {
  11698. + return -ENXIO;
  11699. + goto err_set_drvdata;
  11700. + }
  11701. +
  11702. +#ifdef CONFIG_MTD_PARTITIONS
  11703. + ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions,
  11704. + ARRAY_SIZE(rb4xx_nand_partitions));
  11705. +#else
  11706. + ret = add_mtd_device(&info->mtd);
  11707. +#endif
  11708. + if (ret)
  11709. + goto err_release_nand;
  11710. +
  11711. + return 0;
  11712. +
  11713. +err_release_nand:
  11714. + nand_release(&info->mtd);
  11715. +err_set_drvdata:
  11716. + platform_set_drvdata(pdev, NULL);
  11717. +err_free_info:
  11718. + kfree(info);
  11719. +err_free_gpio:
  11720. + gpio_free(RB4XX_NAND_GPIO_RDY);
  11721. + return ret;
  11722. +}
  11723. +
  11724. +static int __devexit rb4xx_nand_remove(struct platform_device *pdev)
  11725. +{
  11726. + struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
  11727. +
  11728. + nand_release(&info->mtd);
  11729. + platform_set_drvdata(pdev, NULL);
  11730. + kfree(info);
  11731. +
  11732. + return 0;
  11733. +}
  11734. +
  11735. +static struct platform_driver rb4xx_nand_driver = {
  11736. + .probe = rb4xx_nand_probe,
  11737. + .remove = __devexit_p(rb4xx_nand_remove),
  11738. + .driver = {
  11739. + .name = DRV_NAME,
  11740. + .owner = THIS_MODULE,
  11741. + },
  11742. +};
  11743. +
  11744. +static int __init rb4xx_nand_init(void)
  11745. +{
  11746. + return platform_driver_register(&rb4xx_nand_driver);
  11747. +}
  11748. +
  11749. +static void __exit rb4xx_nand_exit(void)
  11750. +{
  11751. + platform_driver_unregister(&rb4xx_nand_driver);
  11752. +}
  11753. +
  11754. +module_init(rb4xx_nand_init);
  11755. +module_exit(rb4xx_nand_exit);
  11756. +
  11757. +MODULE_DESCRIPTION(DRV_DESC);
  11758. +MODULE_VERSION(DRV_VERSION);
  11759. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11760. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  11761. +MODULE_LICENSE("GPL v2");
  11762. diff -Nur linux-2.6.36.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.36/drivers/mtd/nand/rb750_nand.c
  11763. --- linux-2.6.36.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100
  11764. +++ linux-2.6.36/drivers/mtd/nand/rb750_nand.c 2010-12-17 18:34:51.000000000 +0100
  11765. @@ -0,0 +1,360 @@
  11766. +/*
  11767. + * NAND flash driver for the MikroTik RouterBOARD 750
  11768. + *
  11769. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  11770. + *
  11771. + * This program is free software; you can redistribute it and/or modify it
  11772. + * under the terms of the GNU General Public License version 2 as published
  11773. + * by the Free Software Foundation.
  11774. + */
  11775. +
  11776. +#include <linux/init.h>
  11777. +#include <linux/mtd/nand.h>
  11778. +#include <linux/mtd/mtd.h>
  11779. +#include <linux/mtd/partitions.h>
  11780. +#include <linux/platform_device.h>
  11781. +#include <linux/io.h>
  11782. +
  11783. +#include <asm/mach-ar71xx/ar71xx.h>
  11784. +#include <asm/mach-ar71xx/mach-rb750.h>
  11785. +
  11786. +#define DRV_NAME "rb750-nand"
  11787. +#define DRV_VERSION "0.1.0"
  11788. +#define DRV_DESC "NAND flash driver for the RouterBOARD 750"
  11789. +
  11790. +#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0)
  11791. +#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE)
  11792. +#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE)
  11793. +#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE)
  11794. +#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE)
  11795. +#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY)
  11796. +#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE)
  11797. +
  11798. +#define RB750_NAND_DATA_SHIFT 1
  11799. +#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT)
  11800. +#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY)
  11801. +#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \
  11802. + RB750_NAND_NRE | RB750_NAND_NWE | \
  11803. + RB750_NAND_NCE)
  11804. +
  11805. +struct rb750_nand_info {
  11806. + struct nand_chip chip;
  11807. + struct mtd_info mtd;
  11808. +};
  11809. +
  11810. +/*
  11811. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11812. + * will not be able to find the kernel that we load.
  11813. + */
  11814. +static struct nand_ecclayout rb750_nand_ecclayout = {
  11815. + .eccbytes = 6,
  11816. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11817. + .oobavail = 9,
  11818. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11819. +};
  11820. +
  11821. +static struct mtd_partition rb750_nand_partitions[] = {
  11822. + {
  11823. + .name = "booter",
  11824. + .offset = 0,
  11825. + .size = (256 * 1024),
  11826. + .mask_flags = MTD_WRITEABLE,
  11827. + }, {
  11828. + .name = "kernel",
  11829. + .offset = (256 * 1024),
  11830. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11831. + }, {
  11832. + .name = "rootfs",
  11833. + .offset = MTDPART_OFS_NXTBLK,
  11834. + .size = MTDPART_SIZ_FULL,
  11835. + },
  11836. +};
  11837. +
  11838. +static void rb750_nand_write(const u8 *buf, unsigned len)
  11839. +{
  11840. + void __iomem *base = ar71xx_gpio_base;
  11841. + u32 out;
  11842. + unsigned i;
  11843. +
  11844. + /* set data lines to output mode */
  11845. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS,
  11846. + base + GPIO_REG_OE);
  11847. +
  11848. + out = __raw_readl(base + GPIO_REG_OUT);
  11849. + out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE);
  11850. + for (i = 0; i != len; i++) {
  11851. + u32 data;
  11852. +
  11853. + data = buf[i];
  11854. + data <<= RB750_NAND_DATA_SHIFT;
  11855. + data |= out;
  11856. + __raw_writel(data, base + GPIO_REG_OUT);
  11857. +
  11858. + __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT);
  11859. + /* flush write */
  11860. + __raw_readl(base + GPIO_REG_OUT);
  11861. + }
  11862. +
  11863. + /* set data lines to input mode */
  11864. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS,
  11865. + base + GPIO_REG_OE);
  11866. + /* flush write */
  11867. + __raw_readl(base + GPIO_REG_OE);
  11868. +}
  11869. +
  11870. +static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
  11871. + const u8 *verify_buf)
  11872. +{
  11873. + void __iomem *base = ar71xx_gpio_base;
  11874. + unsigned i;
  11875. +
  11876. + for (i = 0; i < len; i++) {
  11877. + u8 data;
  11878. +
  11879. + /* activate RE line */
  11880. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR);
  11881. + /* flush write */
  11882. + __raw_readl(base + GPIO_REG_CLEAR);
  11883. +
  11884. + /* read input lines */
  11885. + data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT;
  11886. +
  11887. + /* deactivate RE line */
  11888. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET);
  11889. +
  11890. + if (read_buf)
  11891. + read_buf[i] = data;
  11892. + else if (verify_buf && verify_buf[i] != data)
  11893. + return -EFAULT;
  11894. + }
  11895. +
  11896. + return 0;
  11897. +}
  11898. +
  11899. +static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
  11900. +{
  11901. + void __iomem *base = ar71xx_gpio_base;
  11902. + u32 func;
  11903. +
  11904. + func = __raw_readl(base + GPIO_REG_FUNC);
  11905. + if (chip >= 0) {
  11906. + /* disable latch */
  11907. + rb750_latch_change(RB750_LVC573_LE, 0);
  11908. +
  11909. + /* disable alternate functions */
  11910. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
  11911. + AR724X_GPIO_FUNC_SPI_EN);
  11912. +
  11913. + /* set input mode for data lines */
  11914. + __raw_writel(__raw_readl(base + GPIO_REG_OE) &
  11915. + ~RB750_NAND_INPUT_BITS,
  11916. + base + GPIO_REG_OE);
  11917. +
  11918. + /* deactivate RE and WE lines */
  11919. + __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE,
  11920. + base + GPIO_REG_SET);
  11921. + /* flush write */
  11922. + (void) __raw_readl(base + GPIO_REG_SET);
  11923. +
  11924. + /* activate CE line */
  11925. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR);
  11926. + } else {
  11927. + /* deactivate CE line */
  11928. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET);
  11929. + /* flush write */
  11930. + (void) __raw_readl(base + GPIO_REG_SET);
  11931. +
  11932. + __raw_writel(__raw_readl(base + GPIO_REG_OE) |
  11933. + RB750_NAND_IO0 | RB750_NAND_RDY,
  11934. + base + GPIO_REG_OE);
  11935. +
  11936. + /* restore alternate functions */
  11937. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
  11938. + AR724X_GPIO_FUNC_JTAG_DISABLE);
  11939. +
  11940. + /* enable latch */
  11941. + rb750_latch_change(0, RB750_LVC573_LE);
  11942. + }
  11943. +}
  11944. +
  11945. +static int rb750_nand_dev_ready(struct mtd_info *mtd)
  11946. +{
  11947. + void __iomem *base = ar71xx_gpio_base;
  11948. +
  11949. + return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY);
  11950. +}
  11951. +
  11952. +static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11953. + unsigned int ctrl)
  11954. +{
  11955. + if (ctrl & NAND_CTRL_CHANGE) {
  11956. + void __iomem *base = ar71xx_gpio_base;
  11957. + u32 t;
  11958. +
  11959. + t = __raw_readl(base + GPIO_REG_OUT);
  11960. +
  11961. + t &= ~(RB750_NAND_CLE | RB750_NAND_ALE);
  11962. + t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0;
  11963. + t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0;
  11964. +
  11965. + __raw_writel(t, base + GPIO_REG_OUT);
  11966. + /* flush write */
  11967. + __raw_readl(base + GPIO_REG_OUT);
  11968. + }
  11969. +
  11970. + if (cmd != NAND_CMD_NONE) {
  11971. + u8 t = cmd;
  11972. + rb750_nand_write(&t, 1);
  11973. + }
  11974. +}
  11975. +
  11976. +static u8 rb750_nand_read_byte(struct mtd_info *mtd)
  11977. +{
  11978. + u8 data = 0;
  11979. + rb750_nand_read_verify(&data, 1, NULL);
  11980. + return data;
  11981. +}
  11982. +
  11983. +static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
  11984. +{
  11985. + rb750_nand_read_verify(buf, len, NULL);
  11986. +}
  11987. +
  11988. +static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11989. +{
  11990. + rb750_nand_write(buf, len);
  11991. +}
  11992. +
  11993. +static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11994. +{
  11995. + return rb750_nand_read_verify(NULL, len, buf);
  11996. +}
  11997. +
  11998. +static void __init rb750_nand_gpio_init(void)
  11999. +{
  12000. + void __iomem *base = ar71xx_gpio_base;
  12001. + u32 out;
  12002. +
  12003. + out = __raw_readl(base + GPIO_REG_OUT);
  12004. +
  12005. + /* setup output levels */
  12006. + __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE,
  12007. + base + GPIO_REG_SET);
  12008. +
  12009. + __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE,
  12010. + base + GPIO_REG_CLEAR);
  12011. +
  12012. + /* setup input lines */
  12013. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS),
  12014. + base + GPIO_REG_OE);
  12015. +
  12016. + /* setup output lines */
  12017. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS,
  12018. + base + GPIO_REG_OE);
  12019. +
  12020. + rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
  12021. +}
  12022. +
  12023. +static int __init rb750_nand_probe(struct platform_device *pdev)
  12024. +{
  12025. + struct rb750_nand_info *info;
  12026. + int ret;
  12027. +
  12028. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  12029. +
  12030. + rb750_nand_gpio_init();
  12031. +
  12032. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  12033. + if (!info)
  12034. + return -ENOMEM;
  12035. +
  12036. + info->chip.priv = &info;
  12037. + info->mtd.priv = &info->chip;
  12038. + info->mtd.owner = THIS_MODULE;
  12039. +
  12040. + info->chip.select_chip = rb750_nand_select_chip;
  12041. + info->chip.cmd_ctrl = rb750_nand_cmd_ctrl;
  12042. + info->chip.dev_ready = rb750_nand_dev_ready;
  12043. + info->chip.read_byte = rb750_nand_read_byte;
  12044. + info->chip.write_buf = rb750_nand_write_buf;
  12045. + info->chip.read_buf = rb750_nand_read_buf;
  12046. + info->chip.verify_buf = rb750_nand_verify_buf;
  12047. +
  12048. + info->chip.chip_delay = 25;
  12049. + info->chip.ecc.mode = NAND_ECC_SOFT;
  12050. + info->chip.options |= NAND_NO_AUTOINCR;
  12051. +
  12052. + platform_set_drvdata(pdev, info);
  12053. +
  12054. + ret = nand_scan_ident(&info->mtd, 1);
  12055. + if (ret) {
  12056. + ret = -ENXIO;
  12057. + goto err_free_info;
  12058. + }
  12059. +
  12060. + if (info->mtd.writesize == 512)
  12061. + info->chip.ecc.layout = &rb750_nand_ecclayout;
  12062. +
  12063. + ret = nand_scan_tail(&info->mtd);
  12064. + if (ret) {
  12065. + return -ENXIO;
  12066. + goto err_set_drvdata;
  12067. + }
  12068. +
  12069. +#ifdef CONFIG_MTD_PARTITIONS
  12070. + ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions,
  12071. + ARRAY_SIZE(rb750_nand_partitions));
  12072. +#else
  12073. + ret = add_mtd_device(&info->mtd);
  12074. +#endif
  12075. + if (ret)
  12076. + goto err_release_nand;
  12077. +
  12078. + return 0;
  12079. +
  12080. + err_release_nand:
  12081. + nand_release(&info->mtd);
  12082. + err_set_drvdata:
  12083. + platform_set_drvdata(pdev, NULL);
  12084. + err_free_info:
  12085. + kfree(info);
  12086. + return ret;
  12087. +}
  12088. +
  12089. +static int __devexit rb750_nand_remove(struct platform_device *pdev)
  12090. +{
  12091. + struct rb750_nand_info *info = platform_get_drvdata(pdev);
  12092. +
  12093. + nand_release(&info->mtd);
  12094. + platform_set_drvdata(pdev, NULL);
  12095. + kfree(info);
  12096. +
  12097. + return 0;
  12098. +}
  12099. +
  12100. +static struct platform_driver rb750_nand_driver = {
  12101. + .probe = rb750_nand_probe,
  12102. + .remove = __devexit_p(rb750_nand_remove),
  12103. + .driver = {
  12104. + .name = DRV_NAME,
  12105. + .owner = THIS_MODULE,
  12106. + },
  12107. +};
  12108. +
  12109. +static int __init rb750_nand_init(void)
  12110. +{
  12111. + return platform_driver_register(&rb750_nand_driver);
  12112. +}
  12113. +
  12114. +static void __exit rb750_nand_exit(void)
  12115. +{
  12116. + platform_driver_unregister(&rb750_nand_driver);
  12117. +}
  12118. +
  12119. +module_init(rb750_nand_init);
  12120. +module_exit(rb750_nand_exit);
  12121. +
  12122. +MODULE_DESCRIPTION(DRV_DESC);
  12123. +MODULE_VERSION(DRV_VERSION);
  12124. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  12125. +MODULE_LICENSE("GPL v2");
  12126. diff -Nur linux-2.6.36.orig/drivers/mtd/wrt160nl_part.c linux-2.6.36/drivers/mtd/wrt160nl_part.c
  12127. --- linux-2.6.36.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100
  12128. +++ linux-2.6.36/drivers/mtd/wrt160nl_part.c 2010-12-17 18:34:51.000000000 +0100
  12129. @@ -0,0 +1,181 @@
  12130. +/*
  12131. + * Copyright (C) 2009 Christian Daniel <cd@maintech.de>
  12132. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  12133. + *
  12134. + * This program is free software; you can redistribute it and/or modify
  12135. + * it under the terms of the GNU General Public License as published by
  12136. + * the Free Software Foundation; either version 2 of the License, or
  12137. + * (at your option) any later version.
  12138. + *
  12139. + * This program is distributed in the hope that it will be useful,
  12140. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12141. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12142. + * GNU General Public License for more details.
  12143. + *
  12144. + * You should have received a copy of the GNU General Public License
  12145. + * along with this program; if not, write to the Free Software
  12146. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12147. + *
  12148. + * TRX flash partition table.
  12149. + * Based on ar7 map by Felix Fietkau <nbd@openwrt.org>
  12150. + *
  12151. + */
  12152. +
  12153. +#include <linux/kernel.h>
  12154. +#include <linux/slab.h>
  12155. +#include <linux/vmalloc.h>
  12156. +
  12157. +#include <linux/mtd/mtd.h>
  12158. +#include <linux/mtd/partitions.h>
  12159. +
  12160. +struct cybertan_header {
  12161. + char magic[4];
  12162. + u8 res1[4];
  12163. + char fw_date[3];
  12164. + char fw_ver[3];
  12165. + char id[4];
  12166. + char hw_ver;
  12167. + char unused;
  12168. + u8 flags[2];
  12169. + u8 res2[10];
  12170. +};
  12171. +
  12172. +#define TRX_PARTS 6
  12173. +#define TRX_MAGIC 0x30524448
  12174. +#define TRX_MAX_OFFSET 3
  12175. +
  12176. +struct trx_header {
  12177. + uint32_t magic; /* "HDR0" */
  12178. + uint32_t len; /* Length of file including header */
  12179. + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
  12180. + uint32_t flag_version; /* 0:15 flags, 16:31 version */
  12181. + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
  12182. +};
  12183. +
  12184. +#define IH_MAGIC 0x27051956 /* Image Magic Number */
  12185. +#define IH_NMLEN 32 /* Image Name Length */
  12186. +
  12187. +struct uimage_header {
  12188. + uint32_t ih_magic; /* Image Header Magic Number */
  12189. + uint32_t ih_hcrc; /* Image Header CRC Checksum */
  12190. + uint32_t ih_time; /* Image Creation Timestamp */
  12191. + uint32_t ih_size; /* Image Data Size */
  12192. + uint32_t ih_load; /* Data» Load Address */
  12193. + uint32_t ih_ep; /* Entry Point Address */
  12194. + uint32_t ih_dcrc; /* Image Data CRC Checksum */
  12195. + uint8_t ih_os; /* Operating System */
  12196. + uint8_t ih_arch; /* CPU architecture */
  12197. + uint8_t ih_type; /* Image Type */
  12198. + uint8_t ih_comp; /* Compression Type */
  12199. + uint8_t ih_name[IH_NMLEN]; /* Image Name */
  12200. +};
  12201. +
  12202. +struct wrt160nl_header {
  12203. + struct cybertan_header cybertan;
  12204. + struct trx_header trx;
  12205. + struct uimage_header uimage;
  12206. +} __attribute__ ((packed));
  12207. +
  12208. +static struct mtd_partition trx_parts[TRX_PARTS];
  12209. +
  12210. +static int wrt160nl_parse_partitions(struct mtd_info *master,
  12211. + struct mtd_partition **pparts,
  12212. + unsigned long origin)
  12213. +{
  12214. + struct wrt160nl_header *header;
  12215. + struct trx_header *theader;
  12216. + struct uimage_header *uheader;
  12217. + size_t retlen;
  12218. + unsigned int kernel_len;
  12219. + int ret;
  12220. +
  12221. + header = vmalloc(sizeof(*header));
  12222. + if (!header) {
  12223. + return -ENOMEM;
  12224. + goto out;
  12225. + }
  12226. +
  12227. + ret = master->read(master, 4 * master->erasesize, sizeof(*header),
  12228. + &retlen, (void *) header);
  12229. + if (ret)
  12230. + goto free_hdr;
  12231. +
  12232. + if (retlen != sizeof(*header)) {
  12233. + ret = -EIO;
  12234. + goto free_hdr;
  12235. + }
  12236. +
  12237. + if (strncmp(header->cybertan.magic, "NL16", 4) != 0) {
  12238. + printk(KERN_NOTICE "%s: no WRT160NL signature found\n",
  12239. + master->name);
  12240. + goto free_hdr;
  12241. + }
  12242. +
  12243. + theader = &header->trx;
  12244. + if (le32_to_cpu(theader->magic) != TRX_MAGIC) {
  12245. + printk(KERN_NOTICE "%s: no TRX header found\n", master->name);
  12246. + goto free_hdr;
  12247. + }
  12248. +
  12249. + uheader = &header->uimage;
  12250. + if (uheader->ih_magic != IH_MAGIC) {
  12251. + printk(KERN_NOTICE "%s: no uImage found\n", master->name);
  12252. + goto free_hdr;
  12253. + }
  12254. +
  12255. + kernel_len = le32_to_cpu(theader->offsets[1]) + sizeof(struct cybertan_header);
  12256. +
  12257. + trx_parts[0].name = "u-boot";
  12258. + trx_parts[0].offset = 0;
  12259. + trx_parts[0].size = 4 * master->erasesize;
  12260. + trx_parts[0].mask_flags = MTD_WRITEABLE;
  12261. +
  12262. + trx_parts[1].name = "kernel";
  12263. + trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size;
  12264. + trx_parts[1].size = kernel_len;
  12265. + trx_parts[1].mask_flags = 0;
  12266. +
  12267. + trx_parts[2].name = "rootfs";
  12268. + trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size;
  12269. + trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size;
  12270. + trx_parts[2].mask_flags = 0;
  12271. +
  12272. + trx_parts[3].name = "nvram";
  12273. + trx_parts[3].offset = master->size - 2 * master->erasesize;
  12274. + trx_parts[3].size = master->erasesize;
  12275. + trx_parts[3].mask_flags = MTD_WRITEABLE;
  12276. +
  12277. + trx_parts[4].name = "art";
  12278. + trx_parts[4].offset = master->size - master->erasesize;
  12279. + trx_parts[4].size = master->erasesize;
  12280. + trx_parts[4].mask_flags = MTD_WRITEABLE;
  12281. +
  12282. + trx_parts[5].name = "firmware";
  12283. + trx_parts[5].offset = 4 * master->erasesize;
  12284. + trx_parts[5].size = master->size - 6 * master->erasesize;
  12285. + trx_parts[5].mask_flags = 0;
  12286. +
  12287. + *pparts = trx_parts;
  12288. + ret = TRX_PARTS;
  12289. +
  12290. + free_hdr:
  12291. + vfree(header);
  12292. + out:
  12293. + return ret;
  12294. +}
  12295. +
  12296. +static struct mtd_part_parser wrt160nl_parser = {
  12297. + .owner = THIS_MODULE,
  12298. + .parse_fn = wrt160nl_parse_partitions,
  12299. + .name = "wrt160nl",
  12300. +};
  12301. +
  12302. +static int __init wrt160nl_parser_init(void)
  12303. +{
  12304. + return register_mtd_parser(&wrt160nl_parser);
  12305. +}
  12306. +
  12307. +module_init(wrt160nl_parser_init);
  12308. +
  12309. +MODULE_LICENSE("GPL");
  12310. +MODULE_AUTHOR("Christian Daniel <cd@maintech.de>");
  12311. diff -Nur linux-2.6.36.orig/drivers/net/Kconfig linux-2.6.36/drivers/net/Kconfig
  12312. --- linux-2.6.36.orig/drivers/net/Kconfig 2010-10-20 22:30:22.000000000 +0200
  12313. +++ linux-2.6.36/drivers/net/Kconfig 2010-12-17 18:34:51.000000000 +0100
  12314. @@ -2045,6 +2045,8 @@
  12315. The safe and default value for this is N.
  12316. +source drivers/net/ag71xx/Kconfig
  12317. +
  12318. config DL2K
  12319. tristate "DL2000/TC902x-based Gigabit Ethernet support"
  12320. depends on PCI
  12321. diff -Nur linux-2.6.36.orig/drivers/net/Makefile linux-2.6.36/drivers/net/Makefile
  12322. --- linux-2.6.36.orig/drivers/net/Makefile 2010-10-20 22:30:22.000000000 +0200
  12323. +++ linux-2.6.36/drivers/net/Makefile 2010-12-17 18:34:51.000000000 +0100
  12324. @@ -109,6 +109,7 @@
  12325. # end link order section
  12326. #
  12327. +obj-$(CONFIG_AG71XX) += ag71xx/
  12328. obj-$(CONFIG_SUNDANCE) += sundance.o
  12329. obj-$(CONFIG_HAMACHI) += hamachi.o
  12330. obj-$(CONFIG_NET) += Space.o loopback.o
  12331. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/Kconfig linux-2.6.36/drivers/net/ag71xx/Kconfig
  12332. --- linux-2.6.36.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  12333. +++ linux-2.6.36/drivers/net/ag71xx/Kconfig 2010-12-17 18:34:51.000000000 +0100
  12334. @@ -0,0 +1,33 @@
  12335. +config AG71XX
  12336. + tristate "Atheros AR71xx built-in ethernet mac support"
  12337. + depends on ATHEROS_AR71XX
  12338. + select PHYLIB
  12339. + help
  12340. + If you wish to compile a kernel for AR71xx/91xx and enable
  12341. + ethernet support, then you should always answer Y to this.
  12342. +
  12343. +if AG71XX
  12344. +
  12345. +config AG71XX_DEBUG
  12346. + bool "Atheros AR71xx built-in ethernet driver debugging"
  12347. + default n
  12348. + help
  12349. + Atheros AR71xx built-in ethernet driver debugging messages.
  12350. +
  12351. +config AG71XX_DEBUG_FS
  12352. + bool "Atheros AR71xx built-in ethernet driver debugfs support"
  12353. + depends on DEBUG_FS
  12354. + default n
  12355. + help
  12356. + Say Y, if you need access to various statistics provided by
  12357. + the ag71xx driver.
  12358. +
  12359. +config AG71XX_AR8216_SUPPORT
  12360. + bool "special support for the Atheros AR8216 switch"
  12361. + default n
  12362. + default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU
  12363. + help
  12364. + Say 'y' here if you want to enable special support for the
  12365. + Atheros AR8216 switch found on some boards.
  12366. +
  12367. +endif
  12368. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/Makefile linux-2.6.36/drivers/net/ag71xx/Makefile
  12369. --- linux-2.6.36.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  12370. +++ linux-2.6.36/drivers/net/ag71xx/Makefile 2010-12-17 18:34:51.000000000 +0100
  12371. @@ -0,0 +1,14 @@
  12372. +#
  12373. +# Makefile for the Atheros AR71xx built-in ethernet macs
  12374. +#
  12375. +
  12376. +ag71xx-y += ag71xx_main.o
  12377. +ag71xx-y += ag71xx_ethtool.o
  12378. +ag71xx-y += ag71xx_phy.o
  12379. +ag71xx-y += ag71xx_mdio.o
  12380. +
  12381. +ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o
  12382. +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o
  12383. +
  12384. +obj-$(CONFIG_AG71XX) += ag71xx.o
  12385. +
  12386. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.36/drivers/net/ag71xx/ag71xx.h
  12387. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100
  12388. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx.h 2010-12-17 18:34:51.000000000 +0100
  12389. @@ -0,0 +1,500 @@
  12390. +/*
  12391. + * Atheros AR71xx built-in ethernet mac driver
  12392. + *
  12393. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12394. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12395. + *
  12396. + * Based on Atheros' AG7100 driver
  12397. + *
  12398. + * This program is free software; you can redistribute it and/or modify it
  12399. + * under the terms of the GNU General Public License version 2 as published
  12400. + * by the Free Software Foundation.
  12401. + */
  12402. +
  12403. +#ifndef __AG71XX_H
  12404. +#define __AG71XX_H
  12405. +
  12406. +#include <linux/kernel.h>
  12407. +#include <linux/version.h>
  12408. +#include <linux/module.h>
  12409. +#include <linux/init.h>
  12410. +#include <linux/types.h>
  12411. +#include <linux/random.h>
  12412. +#include <linux/spinlock.h>
  12413. +#include <linux/interrupt.h>
  12414. +#include <linux/platform_device.h>
  12415. +#include <linux/ethtool.h>
  12416. +#include <linux/etherdevice.h>
  12417. +#include <linux/phy.h>
  12418. +#include <linux/skbuff.h>
  12419. +#include <linux/dma-mapping.h>
  12420. +#include <linux/workqueue.h>
  12421. +
  12422. +#include <linux/bitops.h>
  12423. +
  12424. +#include <asm/mach-ar71xx/ar71xx.h>
  12425. +#include <asm/mach-ar71xx/platform.h>
  12426. +
  12427. +#define ETH_FCS_LEN 4
  12428. +
  12429. +#define AG71XX_DRV_NAME "ag71xx"
  12430. +#define AG71XX_DRV_VERSION "0.5.35"
  12431. +
  12432. +#define AG71XX_NAPI_WEIGHT 64
  12433. +#define AG71XX_OOM_REFILL (1 + HZ/10)
  12434. +
  12435. +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
  12436. +#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
  12437. +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
  12438. +
  12439. +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
  12440. +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
  12441. +
  12442. +#define AG71XX_TX_FIFO_LEN 2048
  12443. +#define AG71XX_TX_MTU_LEN 1536
  12444. +#define AG71XX_RX_PKT_RESERVE 64
  12445. +#define AG71XX_RX_PKT_SIZE \
  12446. + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
  12447. +
  12448. +#define AG71XX_TX_RING_SIZE 64
  12449. +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
  12450. +#define AG71XX_TX_THRES_WAKEUP \
  12451. + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
  12452. +
  12453. +#define AG71XX_RX_RING_SIZE 128
  12454. +
  12455. +#ifdef CONFIG_AG71XX_DEBUG
  12456. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  12457. +#else
  12458. +#define DBG(fmt, args...) do {} while (0)
  12459. +#endif
  12460. +
  12461. +#define ag71xx_assert(_cond) \
  12462. +do { \
  12463. + if (_cond) \
  12464. + break; \
  12465. + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \
  12466. + BUG(); \
  12467. +} while (0)
  12468. +
  12469. +struct ag71xx_desc {
  12470. + u32 data;
  12471. + u32 ctrl;
  12472. +#define DESC_EMPTY BIT(31)
  12473. +#define DESC_MORE BIT(24)
  12474. +#define DESC_PKTLEN_M 0xfff
  12475. + u32 next;
  12476. + u32 pad;
  12477. +} __attribute__((aligned(4)));
  12478. +
  12479. +struct ag71xx_buf {
  12480. + struct sk_buff *skb;
  12481. + struct ag71xx_desc *desc;
  12482. + dma_addr_t dma_addr;
  12483. + u32 pad;
  12484. +};
  12485. +
  12486. +struct ag71xx_ring {
  12487. + struct ag71xx_buf *buf;
  12488. + u8 *descs_cpu;
  12489. + dma_addr_t descs_dma;
  12490. + unsigned int desc_size;
  12491. + unsigned int curr;
  12492. + unsigned int dirty;
  12493. + unsigned int size;
  12494. +};
  12495. +
  12496. +struct ag71xx_mdio {
  12497. + struct mii_bus *mii_bus;
  12498. + int mii_irq[PHY_MAX_ADDR];
  12499. + void __iomem *mdio_base;
  12500. + struct ag71xx_mdio_platform_data *pdata;
  12501. +};
  12502. +
  12503. +struct ag71xx_int_stats {
  12504. + unsigned long rx_pr;
  12505. + unsigned long rx_be;
  12506. + unsigned long rx_of;
  12507. + unsigned long tx_ps;
  12508. + unsigned long tx_be;
  12509. + unsigned long tx_ur;
  12510. + unsigned long total;
  12511. +};
  12512. +
  12513. +struct ag71xx_napi_stats {
  12514. + unsigned long napi_calls;
  12515. + unsigned long rx_count;
  12516. + unsigned long rx_packets;
  12517. + unsigned long rx_packets_max;
  12518. + unsigned long tx_count;
  12519. + unsigned long tx_packets;
  12520. + unsigned long tx_packets_max;
  12521. +
  12522. + unsigned long rx[AG71XX_NAPI_WEIGHT + 1];
  12523. + unsigned long tx[AG71XX_NAPI_WEIGHT + 1];
  12524. +};
  12525. +
  12526. +struct ag71xx_debug {
  12527. + struct dentry *debugfs_dir;
  12528. + struct dentry *debugfs_int_stats;
  12529. + struct dentry *debugfs_napi_stats;
  12530. +
  12531. + struct ag71xx_int_stats int_stats;
  12532. + struct ag71xx_napi_stats napi_stats;
  12533. +};
  12534. +
  12535. +struct ag71xx {
  12536. + void __iomem *mac_base;
  12537. + void __iomem *mii_ctrl;
  12538. +
  12539. + spinlock_t lock;
  12540. + struct platform_device *pdev;
  12541. + struct net_device *dev;
  12542. + struct napi_struct napi;
  12543. + u32 msg_enable;
  12544. +
  12545. + struct ag71xx_ring rx_ring;
  12546. + struct ag71xx_ring tx_ring;
  12547. +
  12548. + struct mii_bus *mii_bus;
  12549. + struct phy_device *phy_dev;
  12550. +
  12551. + unsigned int link;
  12552. + unsigned int speed;
  12553. + int duplex;
  12554. +
  12555. + struct work_struct restart_work;
  12556. + struct timer_list oom_timer;
  12557. +
  12558. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12559. + struct ag71xx_debug debug;
  12560. +#endif
  12561. +};
  12562. +
  12563. +extern struct ethtool_ops ag71xx_ethtool_ops;
  12564. +void ag71xx_link_adjust(struct ag71xx *ag);
  12565. +
  12566. +int ag71xx_mdio_driver_init(void) __init;
  12567. +void ag71xx_mdio_driver_exit(void);
  12568. +
  12569. +int ag71xx_phy_connect(struct ag71xx *ag);
  12570. +void ag71xx_phy_disconnect(struct ag71xx *ag);
  12571. +void ag71xx_phy_start(struct ag71xx *ag);
  12572. +void ag71xx_phy_stop(struct ag71xx *ag);
  12573. +
  12574. +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
  12575. +{
  12576. + return ag->pdev->dev.platform_data;
  12577. +}
  12578. +
  12579. +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
  12580. +{
  12581. + return ((desc->ctrl & DESC_EMPTY) != 0);
  12582. +}
  12583. +
  12584. +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
  12585. +{
  12586. + return (desc->ctrl & DESC_PKTLEN_M);
  12587. +}
  12588. +
  12589. +/* Register offsets */
  12590. +#define AG71XX_REG_MAC_CFG1 0x0000
  12591. +#define AG71XX_REG_MAC_CFG2 0x0004
  12592. +#define AG71XX_REG_MAC_IPG 0x0008
  12593. +#define AG71XX_REG_MAC_HDX 0x000c
  12594. +#define AG71XX_REG_MAC_MFL 0x0010
  12595. +#define AG71XX_REG_MII_CFG 0x0020
  12596. +#define AG71XX_REG_MII_CMD 0x0024
  12597. +#define AG71XX_REG_MII_ADDR 0x0028
  12598. +#define AG71XX_REG_MII_CTRL 0x002c
  12599. +#define AG71XX_REG_MII_STATUS 0x0030
  12600. +#define AG71XX_REG_MII_IND 0x0034
  12601. +#define AG71XX_REG_MAC_IFCTL 0x0038
  12602. +#define AG71XX_REG_MAC_ADDR1 0x0040
  12603. +#define AG71XX_REG_MAC_ADDR2 0x0044
  12604. +#define AG71XX_REG_FIFO_CFG0 0x0048
  12605. +#define AG71XX_REG_FIFO_CFG1 0x004c
  12606. +#define AG71XX_REG_FIFO_CFG2 0x0050
  12607. +#define AG71XX_REG_FIFO_CFG3 0x0054
  12608. +#define AG71XX_REG_FIFO_CFG4 0x0058
  12609. +#define AG71XX_REG_FIFO_CFG5 0x005c
  12610. +#define AG71XX_REG_FIFO_RAM0 0x0060
  12611. +#define AG71XX_REG_FIFO_RAM1 0x0064
  12612. +#define AG71XX_REG_FIFO_RAM2 0x0068
  12613. +#define AG71XX_REG_FIFO_RAM3 0x006c
  12614. +#define AG71XX_REG_FIFO_RAM4 0x0070
  12615. +#define AG71XX_REG_FIFO_RAM5 0x0074
  12616. +#define AG71XX_REG_FIFO_RAM6 0x0078
  12617. +#define AG71XX_REG_FIFO_RAM7 0x007c
  12618. +
  12619. +#define AG71XX_REG_TX_CTRL 0x0180
  12620. +#define AG71XX_REG_TX_DESC 0x0184
  12621. +#define AG71XX_REG_TX_STATUS 0x0188
  12622. +#define AG71XX_REG_RX_CTRL 0x018c
  12623. +#define AG71XX_REG_RX_DESC 0x0190
  12624. +#define AG71XX_REG_RX_STATUS 0x0194
  12625. +#define AG71XX_REG_INT_ENABLE 0x0198
  12626. +#define AG71XX_REG_INT_STATUS 0x019c
  12627. +
  12628. +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
  12629. +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
  12630. +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
  12631. +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
  12632. +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
  12633. +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
  12634. +#define MAC_CFG1_LB BIT(8) /* Loopback mode */
  12635. +#define MAC_CFG1_SR BIT(31) /* Soft Reset */
  12636. +
  12637. +#define MAC_CFG2_FDX BIT(0)
  12638. +#define MAC_CFG2_CRC_EN BIT(1)
  12639. +#define MAC_CFG2_PAD_CRC_EN BIT(2)
  12640. +#define MAC_CFG2_LEN_CHECK BIT(4)
  12641. +#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
  12642. +#define MAC_CFG2_IF_1000 BIT(9)
  12643. +#define MAC_CFG2_IF_10_100 BIT(8)
  12644. +
  12645. +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
  12646. +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
  12647. +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
  12648. +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
  12649. +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
  12650. +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
  12651. + | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
  12652. +
  12653. +#define FIFO_CFG0_ENABLE_SHIFT 8
  12654. +
  12655. +#define FIFO_CFG4_DE BIT(0) /* Drop Event */
  12656. +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
  12657. +#define FIFO_CFG4_FC BIT(2) /* False Carrier */
  12658. +#define FIFO_CFG4_CE BIT(3) /* Code Error */
  12659. +#define FIFO_CFG4_CR BIT(4) /* CRC error */
  12660. +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
  12661. +#define FIFO_CFG4_LO BIT(6) /* Length out of range */
  12662. +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
  12663. +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
  12664. +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
  12665. +#define FIFO_CFG4_DR BIT(10) /* Dribble */
  12666. +#define FIFO_CFG4_LE BIT(11) /* Long Event */
  12667. +#define FIFO_CFG4_CF BIT(12) /* Control Frame */
  12668. +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
  12669. +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
  12670. +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
  12671. +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
  12672. +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
  12673. +
  12674. +#define FIFO_CFG5_DE BIT(0) /* Drop Event */
  12675. +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
  12676. +#define FIFO_CFG5_FC BIT(2) /* False Carrier */
  12677. +#define FIFO_CFG5_CE BIT(3) /* Code Error */
  12678. +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
  12679. +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
  12680. +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
  12681. +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
  12682. +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
  12683. +#define FIFO_CFG5_DR BIT(9) /* Dribble */
  12684. +#define FIFO_CFG5_CF BIT(10) /* Control Frame */
  12685. +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
  12686. +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
  12687. +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
  12688. +#define FIFO_CFG5_LE BIT(14) /* Long Event */
  12689. +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
  12690. +#define FIFO_CFG5_16 BIT(16) /* unknown */
  12691. +#define FIFO_CFG5_17 BIT(17) /* unknown */
  12692. +#define FIFO_CFG5_SF BIT(18) /* Short Frame */
  12693. +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
  12694. +
  12695. +#define AG71XX_INT_TX_PS BIT(0)
  12696. +#define AG71XX_INT_TX_UR BIT(1)
  12697. +#define AG71XX_INT_TX_BE BIT(3)
  12698. +#define AG71XX_INT_RX_PR BIT(4)
  12699. +#define AG71XX_INT_RX_OF BIT(6)
  12700. +#define AG71XX_INT_RX_BE BIT(7)
  12701. +
  12702. +#define MAC_IFCTL_SPEED BIT(16)
  12703. +
  12704. +#define MII_CFG_CLK_DIV_4 0
  12705. +#define MII_CFG_CLK_DIV_6 2
  12706. +#define MII_CFG_CLK_DIV_8 3
  12707. +#define MII_CFG_CLK_DIV_10 4
  12708. +#define MII_CFG_CLK_DIV_14 5
  12709. +#define MII_CFG_CLK_DIV_20 6
  12710. +#define MII_CFG_CLK_DIV_28 7
  12711. +#define MII_CFG_RESET BIT(31)
  12712. +
  12713. +#define MII_CMD_WRITE 0x0
  12714. +#define MII_CMD_READ 0x1
  12715. +#define MII_ADDR_SHIFT 8
  12716. +#define MII_IND_BUSY BIT(0)
  12717. +#define MII_IND_INVALID BIT(2)
  12718. +
  12719. +#define TX_CTRL_TXE BIT(0) /* Tx Enable */
  12720. +
  12721. +#define TX_STATUS_PS BIT(0) /* Packet Sent */
  12722. +#define TX_STATUS_UR BIT(1) /* Tx Underrun */
  12723. +#define TX_STATUS_BE BIT(3) /* Bus Error */
  12724. +
  12725. +#define RX_CTRL_RXE BIT(0) /* Rx Enable */
  12726. +
  12727. +#define RX_STATUS_PR BIT(0) /* Packet Received */
  12728. +#define RX_STATUS_OF BIT(2) /* Rx Overflow */
  12729. +#define RX_STATUS_BE BIT(3) /* Bus Error */
  12730. +
  12731. +#define MII_CTRL_IF_MASK 3
  12732. +#define MII_CTRL_SPEED_SHIFT 4
  12733. +#define MII_CTRL_SPEED_MASK 3
  12734. +#define MII_CTRL_SPEED_10 0
  12735. +#define MII_CTRL_SPEED_100 1
  12736. +#define MII_CTRL_SPEED_1000 2
  12737. +
  12738. +static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
  12739. +{
  12740. + switch (reg) {
  12741. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  12742. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  12743. + break;
  12744. +
  12745. + default:
  12746. + BUG();
  12747. + }
  12748. +}
  12749. +
  12750. +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
  12751. +{
  12752. + ag71xx_check_reg_offset(ag, reg);
  12753. +
  12754. + __raw_writel(value, ag->mac_base + reg);
  12755. + /* flush write */
  12756. + (void) __raw_readl(ag->mac_base + reg);
  12757. +}
  12758. +
  12759. +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
  12760. +{
  12761. + ag71xx_check_reg_offset(ag, reg);
  12762. +
  12763. + return __raw_readl(ag->mac_base + reg);
  12764. +}
  12765. +
  12766. +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
  12767. +{
  12768. + void __iomem *r;
  12769. +
  12770. + ag71xx_check_reg_offset(ag, reg);
  12771. +
  12772. + r = ag->mac_base + reg;
  12773. + __raw_writel(__raw_readl(r) | mask, r);
  12774. + /* flush write */
  12775. + (void)__raw_readl(r);
  12776. +}
  12777. +
  12778. +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
  12779. +{
  12780. + void __iomem *r;
  12781. +
  12782. + ag71xx_check_reg_offset(ag, reg);
  12783. +
  12784. + r = ag->mac_base + reg;
  12785. + __raw_writel(__raw_readl(r) & ~mask, r);
  12786. + /* flush write */
  12787. + (void) __raw_readl(r);
  12788. +}
  12789. +
  12790. +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
  12791. +{
  12792. + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
  12793. +}
  12794. +
  12795. +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
  12796. +{
  12797. + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
  12798. +}
  12799. +
  12800. +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
  12801. +{
  12802. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12803. +
  12804. + if (pdata->is_ar724x)
  12805. + return;
  12806. +
  12807. + __raw_writel(value, ag->mii_ctrl);
  12808. +
  12809. + /* flush write */
  12810. + __raw_readl(ag->mii_ctrl);
  12811. +}
  12812. +
  12813. +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
  12814. +{
  12815. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12816. +
  12817. + if (pdata->is_ar724x)
  12818. + return 0xffffffff;
  12819. +
  12820. + return __raw_readl(ag->mii_ctrl);
  12821. +}
  12822. +
  12823. +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
  12824. + unsigned int mii_if)
  12825. +{
  12826. + u32 t;
  12827. +
  12828. + t = ag71xx_mii_ctrl_rr(ag);
  12829. + t &= ~(MII_CTRL_IF_MASK);
  12830. + t |= (mii_if & MII_CTRL_IF_MASK);
  12831. + ag71xx_mii_ctrl_wr(ag, t);
  12832. +}
  12833. +
  12834. +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
  12835. + unsigned int speed)
  12836. +{
  12837. + u32 t;
  12838. +
  12839. + t = ag71xx_mii_ctrl_rr(ag);
  12840. + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
  12841. + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
  12842. + ag71xx_mii_ctrl_wr(ag, t);
  12843. +}
  12844. +
  12845. +#ifdef CONFIG_AG71XX_AR8216_SUPPORT
  12846. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  12847. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12848. + int pktlen);
  12849. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12850. +{
  12851. + return ag71xx_get_pdata(ag)->has_ar8216;
  12852. +}
  12853. +#else
  12854. +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
  12855. + struct sk_buff *skb)
  12856. +{
  12857. +}
  12858. +
  12859. +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  12860. + struct sk_buff *skb,
  12861. + int pktlen)
  12862. +{
  12863. + return 0;
  12864. +}
  12865. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12866. +{
  12867. + return 0;
  12868. +}
  12869. +#endif
  12870. +
  12871. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12872. +int ag71xx_debugfs_root_init(void);
  12873. +void ag71xx_debugfs_root_exit(void);
  12874. +int ag71xx_debugfs_init(struct ag71xx *ag);
  12875. +void ag71xx_debugfs_exit(struct ag71xx *ag);
  12876. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status);
  12877. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx);
  12878. +#else
  12879. +static inline int ag71xx_debugfs_root_init(void) { return 0; }
  12880. +static inline void ag71xx_debugfs_root_exit(void) {}
  12881. +static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; }
  12882. +static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {}
  12883. +static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
  12884. + u32 status) {}
  12885. +static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
  12886. + int rx, int tx) {}
  12887. +#endif /* CONFIG_AG71XX_DEBUG_FS */
  12888. +
  12889. +#endif /* _AG71XX_H */
  12890. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.36/drivers/net/ag71xx/ag71xx_ar8216.c
  12891. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100
  12892. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_ar8216.c 2010-12-17 18:34:51.000000000 +0100
  12893. @@ -0,0 +1,44 @@
  12894. +/*
  12895. + * Atheros AR71xx built-in ethernet mac driver
  12896. + * Special support for the Atheros ar8216 switch chip
  12897. + *
  12898. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  12899. + *
  12900. + * Based on Atheros' AG7100 driver
  12901. + *
  12902. + * This program is free software; you can redistribute it and/or modify it
  12903. + * under the terms of the GNU General Public License version 2 as published
  12904. + * by the Free Software Foundation.
  12905. + */
  12906. +
  12907. +#include "ag71xx.h"
  12908. +
  12909. +#define AR8216_PACKET_TYPE_MASK 0xf
  12910. +#define AR8216_PACKET_TYPE_NORMAL 0
  12911. +
  12912. +#define AR8216_HEADER_LEN 2
  12913. +
  12914. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
  12915. +{
  12916. + skb_push(skb, AR8216_HEADER_LEN);
  12917. + skb->data[0] = 0x10;
  12918. + skb->data[1] = 0x80;
  12919. +}
  12920. +
  12921. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12922. + int pktlen)
  12923. +{
  12924. + u8 type;
  12925. +
  12926. + type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
  12927. + switch (type) {
  12928. + case AR8216_PACKET_TYPE_NORMAL:
  12929. + break;
  12930. +
  12931. + default:
  12932. + return -EINVAL;
  12933. + }
  12934. +
  12935. + skb_pull(skb, AR8216_HEADER_LEN);
  12936. + return 0;
  12937. +}
  12938. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.36/drivers/net/ag71xx/ag71xx_debugfs.c
  12939. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  12940. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_debugfs.c 2010-12-17 18:34:51.000000000 +0100
  12941. @@ -0,0 +1,197 @@
  12942. +/*
  12943. + * Atheros AR71xx built-in ethernet mac driver
  12944. + *
  12945. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12946. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12947. + *
  12948. + * Based on Atheros' AG7100 driver
  12949. + *
  12950. + * This program is free software; you can redistribute it and/or modify it
  12951. + * under the terms of the GNU General Public License version 2 as published
  12952. + * by the Free Software Foundation.
  12953. + */
  12954. +
  12955. +#include <linux/debugfs.h>
  12956. +
  12957. +#include "ag71xx.h"
  12958. +
  12959. +static struct dentry *ag71xx_debugfs_root;
  12960. +
  12961. +static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file)
  12962. +{
  12963. + file->private_data = inode->i_private;
  12964. + return 0;
  12965. +}
  12966. +
  12967. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status)
  12968. +{
  12969. + if (status)
  12970. + ag->debug.int_stats.total++;
  12971. + if (status & AG71XX_INT_TX_PS)
  12972. + ag->debug.int_stats.tx_ps++;
  12973. + if (status & AG71XX_INT_TX_UR)
  12974. + ag->debug.int_stats.tx_ur++;
  12975. + if (status & AG71XX_INT_TX_BE)
  12976. + ag->debug.int_stats.tx_be++;
  12977. + if (status & AG71XX_INT_RX_PR)
  12978. + ag->debug.int_stats.rx_pr++;
  12979. + if (status & AG71XX_INT_RX_OF)
  12980. + ag->debug.int_stats.rx_of++;
  12981. + if (status & AG71XX_INT_RX_BE)
  12982. + ag->debug.int_stats.rx_be++;
  12983. +}
  12984. +
  12985. +static ssize_t read_file_int_stats(struct file *file, char __user *user_buf,
  12986. + size_t count, loff_t *ppos)
  12987. +{
  12988. +#define PR_INT_STAT(_label, _field) \
  12989. + len += snprintf(buf + len, sizeof(buf) - len, \
  12990. + "%20s: %10lu\n", _label, ag->debug.int_stats._field);
  12991. +
  12992. + struct ag71xx *ag = file->private_data;
  12993. + char buf[256];
  12994. + unsigned int len = 0;
  12995. +
  12996. + PR_INT_STAT("TX Packet Sent", tx_ps);
  12997. + PR_INT_STAT("TX Underrun", tx_ur);
  12998. + PR_INT_STAT("TX Bus Error", tx_be);
  12999. + PR_INT_STAT("RX Packet Received", rx_pr);
  13000. + PR_INT_STAT("RX Overflow", rx_of);
  13001. + PR_INT_STAT("RX Bus Error", rx_be);
  13002. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  13003. + PR_INT_STAT("Total", total);
  13004. +
  13005. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  13006. +#undef PR_INT_STAT
  13007. +}
  13008. +
  13009. +static const struct file_operations ag71xx_fops_int_stats = {
  13010. + .open = ag71xx_debugfs_generic_open,
  13011. + .read = read_file_int_stats,
  13012. + .owner = THIS_MODULE
  13013. +};
  13014. +
  13015. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
  13016. +{
  13017. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  13018. +
  13019. + if (rx) {
  13020. + stats->rx_count++;
  13021. + stats->rx_packets += rx;
  13022. + if (rx <= AG71XX_NAPI_WEIGHT)
  13023. + stats->rx[rx]++;
  13024. + if (rx > stats->rx_packets_max)
  13025. + stats->rx_packets_max = rx;
  13026. + }
  13027. +
  13028. + if (tx) {
  13029. + stats->tx_count++;
  13030. + stats->tx_packets += tx;
  13031. + if (tx <= AG71XX_NAPI_WEIGHT)
  13032. + stats->tx[tx]++;
  13033. + if (tx > stats->tx_packets_max)
  13034. + stats->tx_packets_max = tx;
  13035. + }
  13036. +}
  13037. +
  13038. +static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf,
  13039. + size_t count, loff_t *ppos)
  13040. +{
  13041. + struct ag71xx *ag = file->private_data;
  13042. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  13043. + char buf[2048];
  13044. + unsigned int len = 0;
  13045. + unsigned long rx_avg = 0;
  13046. + unsigned long tx_avg = 0;
  13047. + int i;
  13048. +
  13049. + if (stats->rx_count)
  13050. + rx_avg = stats->rx_packets / stats->rx_count;
  13051. +
  13052. + if (stats->tx_count)
  13053. + tx_avg = stats->tx_packets / stats->tx_count;
  13054. +
  13055. + len += snprintf(buf + len, sizeof(buf) - len, "%3s %10s %10s\n",
  13056. + "len", "rx", "tx");
  13057. +
  13058. + for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++)
  13059. + len += snprintf(buf + len, sizeof(buf) - len,
  13060. + "%3d: %10lu %10lu\n",
  13061. + i, stats->rx[i], stats->tx[i]);
  13062. +
  13063. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  13064. +
  13065. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13066. + "sum", stats->rx_count, stats->tx_count);
  13067. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13068. + "avg", rx_avg, tx_avg);
  13069. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13070. + "max", stats->rx_packets_max, stats->tx_packets_max);
  13071. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13072. + "pkt", stats->rx_packets, stats->tx_packets);
  13073. +
  13074. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  13075. +}
  13076. +
  13077. +static const struct file_operations ag71xx_fops_napi_stats = {
  13078. + .open = ag71xx_debugfs_generic_open,
  13079. + .read = read_file_napi_stats,
  13080. + .owner = THIS_MODULE
  13081. +};
  13082. +
  13083. +void ag71xx_debugfs_exit(struct ag71xx *ag)
  13084. +{
  13085. + debugfs_remove(ag->debug.debugfs_napi_stats);
  13086. + debugfs_remove(ag->debug.debugfs_int_stats);
  13087. + debugfs_remove(ag->debug.debugfs_dir);
  13088. +}
  13089. +
  13090. +int ag71xx_debugfs_init(struct ag71xx *ag)
  13091. +{
  13092. + ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name,
  13093. + ag71xx_debugfs_root);
  13094. + if (!ag->debug.debugfs_dir)
  13095. + goto err;
  13096. +
  13097. + ag->debug.debugfs_int_stats =
  13098. + debugfs_create_file("int_stats",
  13099. + S_IRUGO,
  13100. + ag->debug.debugfs_dir,
  13101. + ag,
  13102. + &ag71xx_fops_int_stats);
  13103. + if (!ag->debug.debugfs_int_stats)
  13104. + goto err;
  13105. +
  13106. + ag->debug.debugfs_napi_stats =
  13107. + debugfs_create_file("napi_stats",
  13108. + S_IRUGO,
  13109. + ag->debug.debugfs_dir,
  13110. + ag,
  13111. + &ag71xx_fops_napi_stats);
  13112. + if (!ag->debug.debugfs_napi_stats)
  13113. + goto err;
  13114. +
  13115. + return 0;
  13116. +
  13117. + err:
  13118. + ag71xx_debugfs_exit(ag);
  13119. + return -ENOMEM;
  13120. +}
  13121. +
  13122. +int ag71xx_debugfs_root_init(void)
  13123. +{
  13124. + if (ag71xx_debugfs_root)
  13125. + return -EBUSY;
  13126. +
  13127. + ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
  13128. + if (!ag71xx_debugfs_root)
  13129. + return -ENOENT;
  13130. +
  13131. + return 0;
  13132. +}
  13133. +
  13134. +void ag71xx_debugfs_root_exit(void)
  13135. +{
  13136. + debugfs_remove(ag71xx_debugfs_root);
  13137. + ag71xx_debugfs_root = NULL;
  13138. +}
  13139. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.36/drivers/net/ag71xx/ag71xx_ethtool.c
  13140. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
  13141. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_ethtool.c 2010-12-17 18:34:51.000000000 +0100
  13142. @@ -0,0 +1,71 @@
  13143. +/*
  13144. + * Atheros AR71xx built-in ethernet mac driver
  13145. + *
  13146. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  13147. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  13148. + *
  13149. + * Based on Atheros' AG7100 driver
  13150. + *
  13151. + * This program is free software; you can redistribute it and/or modify it
  13152. + * under the terms of the GNU General Public License version 2 as published
  13153. + * by the Free Software Foundation.
  13154. + */
  13155. +
  13156. +#include "ag71xx.h"
  13157. +
  13158. +static int ag71xx_ethtool_get_settings(struct net_device *dev,
  13159. + struct ethtool_cmd *cmd)
  13160. +{
  13161. + struct ag71xx *ag = netdev_priv(dev);
  13162. + struct phy_device *phydev = ag->phy_dev;
  13163. +
  13164. + if (!phydev)
  13165. + return -ENODEV;
  13166. +
  13167. + return phy_ethtool_gset(phydev, cmd);
  13168. +}
  13169. +
  13170. +static int ag71xx_ethtool_set_settings(struct net_device *dev,
  13171. + struct ethtool_cmd *cmd)
  13172. +{
  13173. + struct ag71xx *ag = netdev_priv(dev);
  13174. + struct phy_device *phydev = ag->phy_dev;
  13175. +
  13176. + if (!phydev)
  13177. + return -ENODEV;
  13178. +
  13179. + return phy_ethtool_sset(phydev, cmd);
  13180. +}
  13181. +
  13182. +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev,
  13183. + struct ethtool_drvinfo *info)
  13184. +{
  13185. + struct ag71xx *ag = netdev_priv(dev);
  13186. +
  13187. + strcpy(info->driver, ag->pdev->dev.driver->name);
  13188. + strcpy(info->version, AG71XX_DRV_VERSION);
  13189. + strcpy(info->bus_info, dev_name(&ag->pdev->dev));
  13190. +}
  13191. +
  13192. +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev)
  13193. +{
  13194. + struct ag71xx *ag = netdev_priv(dev);
  13195. +
  13196. + return ag->msg_enable;
  13197. +}
  13198. +
  13199. +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level)
  13200. +{
  13201. + struct ag71xx *ag = netdev_priv(dev);
  13202. +
  13203. + ag->msg_enable = msg_level;
  13204. +}
  13205. +
  13206. +struct ethtool_ops ag71xx_ethtool_ops = {
  13207. + .set_settings = ag71xx_ethtool_set_settings,
  13208. + .get_settings = ag71xx_ethtool_get_settings,
  13209. + .get_drvinfo = ag71xx_ethtool_get_drvinfo,
  13210. + .get_msglevel = ag71xx_ethtool_get_msglevel,
  13211. + .set_msglevel = ag71xx_ethtool_set_msglevel,
  13212. + .get_link = ethtool_op_get_link,
  13213. +};
  13214. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.36/drivers/net/ag71xx/ag71xx_main.c
  13215. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100
  13216. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_main.c 2010-12-17 18:34:51.000000000 +0100
  13217. @@ -0,0 +1,1184 @@
  13218. +/*
  13219. + * Atheros AR71xx built-in ethernet mac driver
  13220. + *
  13221. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  13222. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  13223. + *
  13224. + * Based on Atheros' AG7100 driver
  13225. + *
  13226. + * This program is free software; you can redistribute it and/or modify it
  13227. + * under the terms of the GNU General Public License version 2 as published
  13228. + * by the Free Software Foundation.
  13229. + */
  13230. +
  13231. +#include "ag71xx.h"
  13232. +
  13233. +#define AG71XX_DEFAULT_MSG_ENABLE \
  13234. + ( NETIF_MSG_DRV \
  13235. + | NETIF_MSG_PROBE \
  13236. + | NETIF_MSG_LINK \
  13237. + | NETIF_MSG_TIMER \
  13238. + | NETIF_MSG_IFDOWN \
  13239. + | NETIF_MSG_IFUP \
  13240. + | NETIF_MSG_RX_ERR \
  13241. + | NETIF_MSG_TX_ERR )
  13242. +
  13243. +static int ag71xx_msg_level = -1;
  13244. +
  13245. +module_param_named(msg_level, ag71xx_msg_level, int, 0);
  13246. +MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
  13247. +
  13248. +static void ag71xx_dump_dma_regs(struct ag71xx *ag)
  13249. +{
  13250. + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n",
  13251. + ag->dev->name,
  13252. + ag71xx_rr(ag, AG71XX_REG_TX_CTRL),
  13253. + ag71xx_rr(ag, AG71XX_REG_TX_DESC),
  13254. + ag71xx_rr(ag, AG71XX_REG_TX_STATUS));
  13255. +
  13256. + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n",
  13257. + ag->dev->name,
  13258. + ag71xx_rr(ag, AG71XX_REG_RX_CTRL),
  13259. + ag71xx_rr(ag, AG71XX_REG_RX_DESC),
  13260. + ag71xx_rr(ag, AG71XX_REG_RX_STATUS));
  13261. +}
  13262. +
  13263. +static void ag71xx_dump_regs(struct ag71xx *ag)
  13264. +{
  13265. + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n",
  13266. + ag->dev->name,
  13267. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1),
  13268. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13269. + ag71xx_rr(ag, AG71XX_REG_MAC_IPG),
  13270. + ag71xx_rr(ag, AG71XX_REG_MAC_HDX),
  13271. + ag71xx_rr(ag, AG71XX_REG_MAC_MFL));
  13272. + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n",
  13273. + ag->dev->name,
  13274. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13275. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1),
  13276. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2));
  13277. + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n",
  13278. + ag->dev->name,
  13279. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13280. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13281. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13282. + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n",
  13283. + ag->dev->name,
  13284. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13285. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13286. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13287. +}
  13288. +
  13289. +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
  13290. +{
  13291. + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n",
  13292. + ag->dev->name, label, intr,
  13293. + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "",
  13294. + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "",
  13295. + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "",
  13296. + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "",
  13297. + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "",
  13298. + (intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
  13299. +}
  13300. +
  13301. +static void ag71xx_ring_free(struct ag71xx_ring *ring)
  13302. +{
  13303. + kfree(ring->buf);
  13304. +
  13305. + if (ring->descs_cpu)
  13306. + dma_free_coherent(NULL, ring->size * ring->desc_size,
  13307. + ring->descs_cpu, ring->descs_dma);
  13308. +}
  13309. +
  13310. +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
  13311. +{
  13312. + int err;
  13313. + int i;
  13314. +
  13315. + ring->desc_size = sizeof(struct ag71xx_desc);
  13316. + if (ring->desc_size % cache_line_size()) {
  13317. + DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
  13318. + ring, ring->desc_size,
  13319. + roundup(ring->desc_size, cache_line_size()));
  13320. + ring->desc_size = roundup(ring->desc_size, cache_line_size());
  13321. + }
  13322. +
  13323. + ring->descs_cpu = dma_alloc_coherent(NULL, size * ring->desc_size,
  13324. + &ring->descs_dma, GFP_ATOMIC);
  13325. + if (!ring->descs_cpu) {
  13326. + err = -ENOMEM;
  13327. + goto err;
  13328. + }
  13329. +
  13330. + ring->size = size;
  13331. +
  13332. + ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL);
  13333. + if (!ring->buf) {
  13334. + err = -ENOMEM;
  13335. + goto err;
  13336. + }
  13337. +
  13338. + for (i = 0; i < size; i++) {
  13339. + ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
  13340. + DBG("ag71xx: ring %p, desc %d at %p\n",
  13341. + ring, i, ring->buf[i].desc);
  13342. + }
  13343. +
  13344. + return 0;
  13345. +
  13346. + err:
  13347. + return err;
  13348. +}
  13349. +
  13350. +static void ag71xx_ring_tx_clean(struct ag71xx *ag)
  13351. +{
  13352. + struct ag71xx_ring *ring = &ag->tx_ring;
  13353. + struct net_device *dev = ag->dev;
  13354. +
  13355. + while (ring->curr != ring->dirty) {
  13356. + u32 i = ring->dirty % AG71XX_TX_RING_SIZE;
  13357. +
  13358. + if (!ag71xx_desc_empty(ring->buf[i].desc)) {
  13359. + ring->buf[i].desc->ctrl = 0;
  13360. + dev->stats.tx_errors++;
  13361. + }
  13362. +
  13363. + if (ring->buf[i].skb)
  13364. + dev_kfree_skb_any(ring->buf[i].skb);
  13365. +
  13366. + ring->buf[i].skb = NULL;
  13367. +
  13368. + ring->dirty++;
  13369. + }
  13370. +
  13371. + /* flush descriptors */
  13372. + wmb();
  13373. +
  13374. +}
  13375. +
  13376. +static void ag71xx_ring_tx_init(struct ag71xx *ag)
  13377. +{
  13378. + struct ag71xx_ring *ring = &ag->tx_ring;
  13379. + int i;
  13380. +
  13381. + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
  13382. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13383. + ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE));
  13384. +
  13385. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13386. + ring->buf[i].skb = NULL;
  13387. + }
  13388. +
  13389. + /* flush descriptors */
  13390. + wmb();
  13391. +
  13392. + ring->curr = 0;
  13393. + ring->dirty = 0;
  13394. +}
  13395. +
  13396. +static void ag71xx_ring_rx_clean(struct ag71xx *ag)
  13397. +{
  13398. + struct ag71xx_ring *ring = &ag->rx_ring;
  13399. + int i;
  13400. +
  13401. + if (!ring->buf)
  13402. + return;
  13403. +
  13404. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++)
  13405. + if (ring->buf[i].skb) {
  13406. + dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr,
  13407. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  13408. + kfree_skb(ring->buf[i].skb);
  13409. + }
  13410. +}
  13411. +
  13412. +static int ag71xx_rx_reserve(struct ag71xx *ag)
  13413. +{
  13414. + int reserve = 0;
  13415. +
  13416. + if (ag71xx_get_pdata(ag)->is_ar724x) {
  13417. + if (!ag71xx_has_ar8216(ag))
  13418. + reserve = 2;
  13419. +
  13420. + if (ag->phy_dev)
  13421. + reserve += 4 - (ag->phy_dev->pkt_align % 4);
  13422. +
  13423. + reserve %= 4;
  13424. + }
  13425. +
  13426. + return reserve + AG71XX_RX_PKT_RESERVE;
  13427. +}
  13428. +
  13429. +
  13430. +static int ag71xx_ring_rx_init(struct ag71xx *ag)
  13431. +{
  13432. + struct ag71xx_ring *ring = &ag->rx_ring;
  13433. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13434. + unsigned int i;
  13435. + int ret;
  13436. +
  13437. + ret = 0;
  13438. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13439. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13440. + ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE));
  13441. +
  13442. + DBG("ag71xx: RX desc at %p, next is %08x\n",
  13443. + ring->buf[i].desc,
  13444. + ring->buf[i].desc->next);
  13445. + }
  13446. +
  13447. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13448. + struct sk_buff *skb;
  13449. + dma_addr_t dma_addr;
  13450. +
  13451. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13452. + if (!skb) {
  13453. + ret = -ENOMEM;
  13454. + break;
  13455. + }
  13456. +
  13457. + skb->dev = ag->dev;
  13458. + skb_reserve(skb, reserve);
  13459. +
  13460. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13461. + AG71XX_RX_PKT_SIZE,
  13462. + DMA_FROM_DEVICE);
  13463. + ring->buf[i].skb = skb;
  13464. + ring->buf[i].dma_addr = dma_addr;
  13465. + ring->buf[i].desc->data = (u32) dma_addr;
  13466. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13467. + }
  13468. +
  13469. + /* flush descriptors */
  13470. + wmb();
  13471. +
  13472. + ring->curr = 0;
  13473. + ring->dirty = 0;
  13474. +
  13475. + return ret;
  13476. +}
  13477. +
  13478. +static int ag71xx_ring_rx_refill(struct ag71xx *ag)
  13479. +{
  13480. + struct ag71xx_ring *ring = &ag->rx_ring;
  13481. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13482. + unsigned int count;
  13483. +
  13484. + count = 0;
  13485. + for (; ring->curr - ring->dirty > 0; ring->dirty++) {
  13486. + unsigned int i;
  13487. +
  13488. + i = ring->dirty % AG71XX_RX_RING_SIZE;
  13489. +
  13490. + if (ring->buf[i].skb == NULL) {
  13491. + dma_addr_t dma_addr;
  13492. + struct sk_buff *skb;
  13493. +
  13494. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13495. + if (skb == NULL)
  13496. + break;
  13497. +
  13498. + skb_reserve(skb, reserve);
  13499. + skb->dev = ag->dev;
  13500. +
  13501. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13502. + AG71XX_RX_PKT_SIZE,
  13503. + DMA_FROM_DEVICE);
  13504. +
  13505. + ring->buf[i].skb = skb;
  13506. + ring->buf[i].dma_addr = dma_addr;
  13507. + ring->buf[i].desc->data = (u32) dma_addr;
  13508. + }
  13509. +
  13510. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13511. + count++;
  13512. + }
  13513. +
  13514. + /* flush descriptors */
  13515. + wmb();
  13516. +
  13517. + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count);
  13518. +
  13519. + return count;
  13520. +}
  13521. +
  13522. +static int ag71xx_rings_init(struct ag71xx *ag)
  13523. +{
  13524. + int ret;
  13525. +
  13526. + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
  13527. + if (ret)
  13528. + return ret;
  13529. +
  13530. + ag71xx_ring_tx_init(ag);
  13531. +
  13532. + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
  13533. + if (ret)
  13534. + return ret;
  13535. +
  13536. + ret = ag71xx_ring_rx_init(ag);
  13537. + return ret;
  13538. +}
  13539. +
  13540. +static void ag71xx_rings_cleanup(struct ag71xx *ag)
  13541. +{
  13542. + ag71xx_ring_rx_clean(ag);
  13543. + ag71xx_ring_free(&ag->rx_ring);
  13544. +
  13545. + ag71xx_ring_tx_clean(ag);
  13546. + ag71xx_ring_free(&ag->tx_ring);
  13547. +}
  13548. +
  13549. +static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
  13550. +{
  13551. + switch (ag->speed) {
  13552. + case SPEED_1000:
  13553. + return "1000";
  13554. + case SPEED_100:
  13555. + return "100";
  13556. + case SPEED_10:
  13557. + return "10";
  13558. + }
  13559. +
  13560. + return "?";
  13561. +}
  13562. +
  13563. +void ag71xx_link_adjust(struct ag71xx *ag)
  13564. +{
  13565. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13566. + u32 cfg2;
  13567. + u32 ifctl;
  13568. + u32 fifo5;
  13569. + u32 mii_speed;
  13570. +
  13571. + if (!ag->link) {
  13572. + netif_carrier_off(ag->dev);
  13573. + if (netif_msg_link(ag))
  13574. + printk(KERN_INFO "%s: link down\n", ag->dev->name);
  13575. + return;
  13576. + }
  13577. +
  13578. + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
  13579. + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
  13580. + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
  13581. +
  13582. + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
  13583. + ifctl &= ~(MAC_IFCTL_SPEED);
  13584. +
  13585. + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
  13586. + fifo5 &= ~FIFO_CFG5_BM;
  13587. +
  13588. + switch (ag->speed) {
  13589. + case SPEED_1000:
  13590. + mii_speed = MII_CTRL_SPEED_1000;
  13591. + cfg2 |= MAC_CFG2_IF_1000;
  13592. + fifo5 |= FIFO_CFG5_BM;
  13593. + break;
  13594. + case SPEED_100:
  13595. + mii_speed = MII_CTRL_SPEED_100;
  13596. + cfg2 |= MAC_CFG2_IF_10_100;
  13597. + ifctl |= MAC_IFCTL_SPEED;
  13598. + break;
  13599. + case SPEED_10:
  13600. + mii_speed = MII_CTRL_SPEED_10;
  13601. + cfg2 |= MAC_CFG2_IF_10_100;
  13602. + break;
  13603. + default:
  13604. + BUG();
  13605. + return;
  13606. + }
  13607. +
  13608. + if (pdata->is_ar91xx)
  13609. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
  13610. + else if (pdata->is_ar724x)
  13611. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3);
  13612. + else
  13613. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
  13614. +
  13615. + if (pdata->set_pll)
  13616. + pdata->set_pll(ag->speed);
  13617. +
  13618. + ag71xx_mii_ctrl_set_speed(ag, mii_speed);
  13619. +
  13620. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
  13621. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
  13622. + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
  13623. +
  13624. + netif_carrier_on(ag->dev);
  13625. + if (netif_msg_link(ag))
  13626. + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
  13627. + ag->dev->name,
  13628. + ag71xx_speed_str(ag),
  13629. + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half");
  13630. +
  13631. + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
  13632. + ag->dev->name,
  13633. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13634. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13635. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13636. +
  13637. + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
  13638. + ag->dev->name,
  13639. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13640. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13641. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13642. +
  13643. + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
  13644. + ag->dev->name,
  13645. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13646. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13647. + ag71xx_mii_ctrl_rr(ag));
  13648. +}
  13649. +
  13650. +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
  13651. +{
  13652. + u32 t;
  13653. +
  13654. + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
  13655. + | (((u32) mac[3]) << 8) | ((u32) mac[2]);
  13656. +
  13657. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
  13658. +
  13659. + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
  13660. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
  13661. +}
  13662. +
  13663. +static void ag71xx_dma_reset(struct ag71xx *ag)
  13664. +{
  13665. + u32 val;
  13666. + int i;
  13667. +
  13668. + ag71xx_dump_dma_regs(ag);
  13669. +
  13670. + /* stop RX and TX */
  13671. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  13672. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  13673. +
  13674. + /* clear descriptor addresses */
  13675. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
  13676. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
  13677. +
  13678. + /* clear pending RX/TX interrupts */
  13679. + for (i = 0; i < 256; i++) {
  13680. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  13681. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13682. + }
  13683. +
  13684. + /* clear pending errors */
  13685. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
  13686. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
  13687. +
  13688. + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  13689. + if (val)
  13690. + printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
  13691. + ag->dev->name, val);
  13692. +
  13693. + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  13694. +
  13695. + /* mask out reserved bits */
  13696. + val &= ~0xff000000;
  13697. +
  13698. + if (val)
  13699. + printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
  13700. + ag->dev->name, val);
  13701. +
  13702. + ag71xx_dump_dma_regs(ag);
  13703. +}
  13704. +
  13705. +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
  13706. + MAC_CFG1_SRX | MAC_CFG1_STX)
  13707. +
  13708. +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
  13709. +
  13710. +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
  13711. + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
  13712. + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
  13713. + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
  13714. + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
  13715. + FIFO_CFG4_VT)
  13716. +
  13717. +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
  13718. + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
  13719. + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
  13720. + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
  13721. + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
  13722. + FIFO_CFG5_17 | FIFO_CFG5_SF)
  13723. +
  13724. +static void ag71xx_hw_init(struct ag71xx *ag)
  13725. +{
  13726. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13727. +
  13728. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
  13729. + udelay(20);
  13730. +
  13731. + ar71xx_device_stop(pdata->reset_bit);
  13732. + mdelay(100);
  13733. + ar71xx_device_start(pdata->reset_bit);
  13734. + mdelay(100);
  13735. +
  13736. + /* setup MAC configuration registers */
  13737. + if (pdata->is_ar724x)
  13738. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1,
  13739. + MAC_CFG1_INIT | MAC_CFG1_TFC | MAC_CFG1_RFC);
  13740. + else
  13741. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
  13742. +
  13743. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
  13744. + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
  13745. +
  13746. + /* setup max frame length */
  13747. + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
  13748. +
  13749. + /* setup MII interface type */
  13750. + ag71xx_mii_ctrl_set_if(ag, pdata->mii_if);
  13751. +
  13752. + /* setup FIFO configuration registers */
  13753. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
  13754. + if (pdata->is_ar724x) {
  13755. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1);
  13756. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2);
  13757. + } else {
  13758. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
  13759. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
  13760. + }
  13761. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
  13762. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
  13763. +
  13764. + ag71xx_dma_reset(ag);
  13765. +}
  13766. +
  13767. +static void ag71xx_hw_start(struct ag71xx *ag)
  13768. +{
  13769. + /* start RX engine */
  13770. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  13771. +
  13772. + /* enable interrupts */
  13773. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
  13774. +}
  13775. +
  13776. +static void ag71xx_hw_stop(struct ag71xx *ag)
  13777. +{
  13778. + /* disable all interrupts */
  13779. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
  13780. +
  13781. + ag71xx_dma_reset(ag);
  13782. +}
  13783. +
  13784. +static int ag71xx_open(struct net_device *dev)
  13785. +{
  13786. + struct ag71xx *ag = netdev_priv(dev);
  13787. + int ret;
  13788. +
  13789. + ret = ag71xx_rings_init(ag);
  13790. + if (ret)
  13791. + goto err;
  13792. +
  13793. + napi_enable(&ag->napi);
  13794. +
  13795. + netif_carrier_off(dev);
  13796. + ag71xx_phy_start(ag);
  13797. +
  13798. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);
  13799. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma);
  13800. +
  13801. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  13802. +
  13803. + ag71xx_hw_start(ag);
  13804. +
  13805. + netif_start_queue(dev);
  13806. +
  13807. + return 0;
  13808. +
  13809. + err:
  13810. + ag71xx_rings_cleanup(ag);
  13811. + return ret;
  13812. +}
  13813. +
  13814. +static int ag71xx_stop(struct net_device *dev)
  13815. +{
  13816. + struct ag71xx *ag = netdev_priv(dev);
  13817. + unsigned long flags;
  13818. +
  13819. + netif_carrier_off(dev);
  13820. + ag71xx_phy_stop(ag);
  13821. +
  13822. + spin_lock_irqsave(&ag->lock, flags);
  13823. +
  13824. + netif_stop_queue(dev);
  13825. +
  13826. + ag71xx_hw_stop(ag);
  13827. +
  13828. + napi_disable(&ag->napi);
  13829. + del_timer_sync(&ag->oom_timer);
  13830. +
  13831. + spin_unlock_irqrestore(&ag->lock, flags);
  13832. +
  13833. + ag71xx_rings_cleanup(ag);
  13834. +
  13835. + return 0;
  13836. +}
  13837. +
  13838. +static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
  13839. + struct net_device *dev)
  13840. +{
  13841. + struct ag71xx *ag = netdev_priv(dev);
  13842. + struct ag71xx_ring *ring = &ag->tx_ring;
  13843. + struct ag71xx_desc *desc;
  13844. + dma_addr_t dma_addr;
  13845. + int i;
  13846. +
  13847. + i = ring->curr % AG71XX_TX_RING_SIZE;
  13848. + desc = ring->buf[i].desc;
  13849. +
  13850. + if (!ag71xx_desc_empty(desc))
  13851. + goto err_drop;
  13852. +
  13853. + if (ag71xx_has_ar8216(ag))
  13854. + ag71xx_add_ar8216_header(ag, skb);
  13855. +
  13856. + if (skb->len <= 0) {
  13857. + DBG("%s: packet len is too small\n", ag->dev->name);
  13858. + goto err_drop;
  13859. + }
  13860. +
  13861. + dma_addr = dma_map_single(&dev->dev, skb->data, skb->len,
  13862. + DMA_TO_DEVICE);
  13863. +
  13864. + ring->buf[i].skb = skb;
  13865. +
  13866. + /* setup descriptor fields */
  13867. + desc->data = (u32) dma_addr;
  13868. + desc->ctrl = (skb->len & DESC_PKTLEN_M);
  13869. +
  13870. + /* flush descriptor */
  13871. + wmb();
  13872. +
  13873. + ring->curr++;
  13874. + if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) {
  13875. + DBG("%s: tx queue full\n", ag->dev->name);
  13876. + netif_stop_queue(dev);
  13877. + }
  13878. +
  13879. + DBG("%s: packet injected into TX queue\n", ag->dev->name);
  13880. +
  13881. + /* enable TX engine */
  13882. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
  13883. +
  13884. + return NETDEV_TX_OK;
  13885. +
  13886. + err_drop:
  13887. + dev->stats.tx_dropped++;
  13888. +
  13889. + dev_kfree_skb(skb);
  13890. + return NETDEV_TX_OK;
  13891. +}
  13892. +
  13893. +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  13894. +{
  13895. + struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;
  13896. + struct ag71xx *ag = netdev_priv(dev);
  13897. + int ret;
  13898. +
  13899. + switch (cmd) {
  13900. + case SIOCETHTOOL:
  13901. + if (ag->phy_dev == NULL)
  13902. + break;
  13903. +
  13904. + spin_lock_irq(&ag->lock);
  13905. + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data);
  13906. + spin_unlock_irq(&ag->lock);
  13907. + return ret;
  13908. +
  13909. + case SIOCSIFHWADDR:
  13910. + if (copy_from_user
  13911. + (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
  13912. + return -EFAULT;
  13913. + return 0;
  13914. +
  13915. + case SIOCGIFHWADDR:
  13916. + if (copy_to_user
  13917. + (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
  13918. + return -EFAULT;
  13919. + return 0;
  13920. +
  13921. + case SIOCGMIIPHY:
  13922. + case SIOCGMIIREG:
  13923. + case SIOCSMIIREG:
  13924. + if (ag->phy_dev == NULL)
  13925. + break;
  13926. +
  13927. + return phy_mii_ioctl(ag->phy_dev, data, cmd);
  13928. +
  13929. + default:
  13930. + break;
  13931. + }
  13932. +
  13933. + return -EOPNOTSUPP;
  13934. +}
  13935. +
  13936. +static void ag71xx_oom_timer_handler(unsigned long data)
  13937. +{
  13938. + struct net_device *dev = (struct net_device *) data;
  13939. + struct ag71xx *ag = netdev_priv(dev);
  13940. +
  13941. + napi_schedule(&ag->napi);
  13942. +}
  13943. +
  13944. +static void ag71xx_tx_timeout(struct net_device *dev)
  13945. +{
  13946. + struct ag71xx *ag = netdev_priv(dev);
  13947. +
  13948. + if (netif_msg_tx_err(ag))
  13949. + printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
  13950. +
  13951. + schedule_work(&ag->restart_work);
  13952. +}
  13953. +
  13954. +static void ag71xx_restart_work_func(struct work_struct *work)
  13955. +{
  13956. + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
  13957. +
  13958. + ag71xx_stop(ag->dev);
  13959. + ag71xx_open(ag->dev);
  13960. +}
  13961. +
  13962. +static int ag71xx_tx_packets(struct ag71xx *ag)
  13963. +{
  13964. + struct ag71xx_ring *ring = &ag->tx_ring;
  13965. + int sent;
  13966. +
  13967. + DBG("%s: processing TX ring\n", ag->dev->name);
  13968. +
  13969. + sent = 0;
  13970. + while (ring->dirty != ring->curr) {
  13971. + unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE;
  13972. + struct ag71xx_desc *desc = ring->buf[i].desc;
  13973. + struct sk_buff *skb = ring->buf[i].skb;
  13974. +
  13975. + if (!ag71xx_desc_empty(desc))
  13976. + break;
  13977. +
  13978. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13979. +
  13980. + ag->dev->stats.tx_bytes += skb->len;
  13981. + ag->dev->stats.tx_packets++;
  13982. +
  13983. + dev_kfree_skb_any(skb);
  13984. + ring->buf[i].skb = NULL;
  13985. +
  13986. + ring->dirty++;
  13987. + sent++;
  13988. + }
  13989. +
  13990. + DBG("%s: %d packets sent out\n", ag->dev->name, sent);
  13991. +
  13992. + if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP)
  13993. + netif_wake_queue(ag->dev);
  13994. +
  13995. + return sent;
  13996. +}
  13997. +
  13998. +static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
  13999. +{
  14000. + struct net_device *dev = ag->dev;
  14001. + struct ag71xx_ring *ring = &ag->rx_ring;
  14002. + int done = 0;
  14003. +
  14004. + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n",
  14005. + dev->name, limit, ring->curr, ring->dirty);
  14006. +
  14007. + while (done < limit) {
  14008. + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
  14009. + struct ag71xx_desc *desc = ring->buf[i].desc;
  14010. + struct sk_buff *skb;
  14011. + int pktlen;
  14012. + int err = 0;
  14013. +
  14014. + if (ag71xx_desc_empty(desc))
  14015. + break;
  14016. +
  14017. + if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) {
  14018. + ag71xx_assert(0);
  14019. + break;
  14020. + }
  14021. +
  14022. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  14023. +
  14024. + skb = ring->buf[i].skb;
  14025. + pktlen = ag71xx_desc_pktlen(desc);
  14026. + pktlen -= ETH_FCS_LEN;
  14027. +
  14028. + dma_unmap_single(&dev->dev, ring->buf[i].dma_addr,
  14029. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  14030. +
  14031. + dev->last_rx = jiffies;
  14032. + dev->stats.rx_packets++;
  14033. + dev->stats.rx_bytes += pktlen;
  14034. +
  14035. + skb_put(skb, pktlen);
  14036. + if (ag71xx_has_ar8216(ag))
  14037. + err = ag71xx_remove_ar8216_header(ag, skb, pktlen);
  14038. +
  14039. + if (err) {
  14040. + dev->stats.rx_dropped++;
  14041. + kfree_skb(skb);
  14042. + } else {
  14043. + skb->dev = dev;
  14044. + skb->ip_summed = CHECKSUM_NONE;
  14045. + if (ag->phy_dev) {
  14046. + ag->phy_dev->netif_receive_skb(skb);
  14047. + } else {
  14048. + skb->protocol = eth_type_trans(skb, dev);
  14049. + netif_receive_skb(skb);
  14050. + }
  14051. + }
  14052. +
  14053. + ring->buf[i].skb = NULL;
  14054. + done++;
  14055. +
  14056. + ring->curr++;
  14057. + }
  14058. +
  14059. + ag71xx_ring_rx_refill(ag);
  14060. +
  14061. + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n",
  14062. + dev->name, ring->curr, ring->dirty, done);
  14063. +
  14064. + return done;
  14065. +}
  14066. +
  14067. +static int ag71xx_poll(struct napi_struct *napi, int limit)
  14068. +{
  14069. + struct ag71xx *ag = container_of(napi, struct ag71xx, napi);
  14070. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14071. + struct net_device *dev = ag->dev;
  14072. + struct ag71xx_ring *rx_ring;
  14073. + unsigned long flags;
  14074. + u32 status;
  14075. + int tx_done;
  14076. + int rx_done;
  14077. +
  14078. + pdata->ddr_flush();
  14079. + tx_done = ag71xx_tx_packets(ag);
  14080. +
  14081. + DBG("%s: processing RX ring\n", dev->name);
  14082. + rx_done = ag71xx_rx_packets(ag, limit);
  14083. +
  14084. + ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done);
  14085. +
  14086. + rx_ring = &ag->rx_ring;
  14087. + if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL)
  14088. + goto oom;
  14089. +
  14090. + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  14091. + if (unlikely(status & RX_STATUS_OF)) {
  14092. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
  14093. + dev->stats.rx_fifo_errors++;
  14094. +
  14095. + /* restart RX */
  14096. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  14097. + }
  14098. +
  14099. + if (rx_done < limit) {
  14100. + if (status & RX_STATUS_PR)
  14101. + goto more;
  14102. +
  14103. + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  14104. + if (status & TX_STATUS_PS)
  14105. + goto more;
  14106. +
  14107. + DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n",
  14108. + dev->name, rx_done, tx_done, limit);
  14109. +
  14110. + napi_complete(napi);
  14111. +
  14112. + /* enable interrupts */
  14113. + spin_lock_irqsave(&ag->lock, flags);
  14114. + ag71xx_int_enable(ag, AG71XX_INT_POLL);
  14115. + spin_unlock_irqrestore(&ag->lock, flags);
  14116. + return rx_done;
  14117. + }
  14118. +
  14119. + more:
  14120. + DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n",
  14121. + dev->name, rx_done, tx_done, limit);
  14122. + return rx_done;
  14123. +
  14124. + oom:
  14125. + if (netif_msg_rx_err(ag))
  14126. + printk(KERN_DEBUG "%s: out of memory\n", dev->name);
  14127. +
  14128. + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
  14129. + napi_complete(napi);
  14130. + return 0;
  14131. +}
  14132. +
  14133. +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
  14134. +{
  14135. + struct net_device *dev = dev_id;
  14136. + struct ag71xx *ag = netdev_priv(dev);
  14137. + u32 status;
  14138. +
  14139. + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
  14140. + ag71xx_dump_intr(ag, "raw", status);
  14141. +
  14142. + if (unlikely(!status))
  14143. + return IRQ_NONE;
  14144. +
  14145. + if (unlikely(status & AG71XX_INT_ERR)) {
  14146. + if (status & AG71XX_INT_TX_BE) {
  14147. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE);
  14148. + dev_err(&dev->dev, "TX BUS error\n");
  14149. + }
  14150. + if (status & AG71XX_INT_RX_BE) {
  14151. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE);
  14152. + dev_err(&dev->dev, "RX BUS error\n");
  14153. + }
  14154. + }
  14155. +
  14156. + if (likely(status & AG71XX_INT_POLL)) {
  14157. + ag71xx_int_disable(ag, AG71XX_INT_POLL);
  14158. + DBG("%s: enable polling mode\n", dev->name);
  14159. + napi_schedule(&ag->napi);
  14160. + }
  14161. +
  14162. + ag71xx_debugfs_update_int_stats(ag, status);
  14163. +
  14164. + return IRQ_HANDLED;
  14165. +}
  14166. +
  14167. +static void ag71xx_set_multicast_list(struct net_device *dev)
  14168. +{
  14169. + /* TODO */
  14170. +}
  14171. +
  14172. +#ifdef CONFIG_NET_POLL_CONTROLLER
  14173. +/*
  14174. + * Polling 'interrupt' - used by things like netconsole to send skbs
  14175. + * without having to re-enable interrupts. It's not called while
  14176. + * the interrupt routine is executing.
  14177. + */
  14178. +static void ag71xx_netpoll(struct net_device *dev)
  14179. +{
  14180. + disable_irq(dev->irq);
  14181. + ag71xx_interrupt(dev->irq, dev);
  14182. + enable_irq(dev->irq);
  14183. +}
  14184. +#endif
  14185. +
  14186. +static const struct net_device_ops ag71xx_netdev_ops = {
  14187. + .ndo_open = ag71xx_open,
  14188. + .ndo_stop = ag71xx_stop,
  14189. + .ndo_start_xmit = ag71xx_hard_start_xmit,
  14190. + .ndo_set_multicast_list = ag71xx_set_multicast_list,
  14191. + .ndo_do_ioctl = ag71xx_do_ioctl,
  14192. + .ndo_tx_timeout = ag71xx_tx_timeout,
  14193. + .ndo_change_mtu = eth_change_mtu,
  14194. + .ndo_set_mac_address = eth_mac_addr,
  14195. + .ndo_validate_addr = eth_validate_addr,
  14196. +#ifdef CONFIG_NET_POLL_CONTROLLER
  14197. + .ndo_poll_controller = ag71xx_netpoll,
  14198. +#endif
  14199. +};
  14200. +
  14201. +static int __init ag71xx_probe(struct platform_device *pdev)
  14202. +{
  14203. + struct net_device *dev;
  14204. + struct resource *res;
  14205. + struct ag71xx *ag;
  14206. + struct ag71xx_platform_data *pdata;
  14207. + int err;
  14208. +
  14209. + pdata = pdev->dev.platform_data;
  14210. + if (!pdata) {
  14211. + dev_err(&pdev->dev, "no platform data specified\n");
  14212. + err = -ENXIO;
  14213. + goto err_out;
  14214. + }
  14215. +
  14216. + if (pdata->mii_bus_dev == NULL) {
  14217. + dev_err(&pdev->dev, "no MII bus device specified\n");
  14218. + err = -EINVAL;
  14219. + goto err_out;
  14220. + }
  14221. +
  14222. + dev = alloc_etherdev(sizeof(*ag));
  14223. + if (!dev) {
  14224. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  14225. + err = -ENOMEM;
  14226. + goto err_out;
  14227. + }
  14228. +
  14229. + SET_NETDEV_DEV(dev, &pdev->dev);
  14230. +
  14231. + ag = netdev_priv(dev);
  14232. + ag->pdev = pdev;
  14233. + ag->dev = dev;
  14234. + ag->msg_enable = netif_msg_init(ag71xx_msg_level,
  14235. + AG71XX_DEFAULT_MSG_ENABLE);
  14236. + spin_lock_init(&ag->lock);
  14237. +
  14238. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base");
  14239. + if (!res) {
  14240. + dev_err(&pdev->dev, "no mac_base resource found\n");
  14241. + err = -ENXIO;
  14242. + goto err_out;
  14243. + }
  14244. +
  14245. + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14246. + if (!ag->mac_base) {
  14247. + dev_err(&pdev->dev, "unable to ioremap mac_base\n");
  14248. + err = -ENOMEM;
  14249. + goto err_free_dev;
  14250. + }
  14251. +
  14252. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl");
  14253. + if (!res) {
  14254. + dev_err(&pdev->dev, "no mii_ctrl resource found\n");
  14255. + err = -ENXIO;
  14256. + goto err_unmap_base;
  14257. + }
  14258. +
  14259. + ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1);
  14260. + if (!ag->mii_ctrl) {
  14261. + dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n");
  14262. + err = -ENOMEM;
  14263. + goto err_unmap_base;
  14264. + }
  14265. +
  14266. + dev->irq = platform_get_irq(pdev, 0);
  14267. + err = request_irq(dev->irq, ag71xx_interrupt,
  14268. + IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
  14269. + dev->name, dev);
  14270. + if (err) {
  14271. + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
  14272. + goto err_unmap_mii_ctrl;
  14273. + }
  14274. +
  14275. + dev->base_addr = (unsigned long)ag->mac_base;
  14276. + dev->netdev_ops = &ag71xx_netdev_ops;
  14277. + dev->ethtool_ops = &ag71xx_ethtool_ops;
  14278. +
  14279. + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
  14280. +
  14281. + init_timer(&ag->oom_timer);
  14282. + ag->oom_timer.data = (unsigned long) dev;
  14283. + ag->oom_timer.function = ag71xx_oom_timer_handler;
  14284. +
  14285. + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
  14286. +
  14287. + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
  14288. +
  14289. + err = register_netdev(dev);
  14290. + if (err) {
  14291. + dev_err(&pdev->dev, "unable to register net device\n");
  14292. + goto err_free_irq;
  14293. + }
  14294. +
  14295. + printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n",
  14296. + dev->name, dev->base_addr, dev->irq);
  14297. +
  14298. + ag71xx_dump_regs(ag);
  14299. +
  14300. + ag71xx_hw_init(ag);
  14301. +
  14302. + ag71xx_dump_regs(ag);
  14303. +
  14304. + err = ag71xx_phy_connect(ag);
  14305. + if (err)
  14306. + goto err_unregister_netdev;
  14307. +
  14308. + err = ag71xx_debugfs_init(ag);
  14309. + if (err)
  14310. + goto err_phy_disconnect;
  14311. +
  14312. + platform_set_drvdata(pdev, dev);
  14313. +
  14314. + return 0;
  14315. +
  14316. + err_phy_disconnect:
  14317. + ag71xx_phy_disconnect(ag);
  14318. + err_unregister_netdev:
  14319. + unregister_netdev(dev);
  14320. + err_free_irq:
  14321. + free_irq(dev->irq, dev);
  14322. + err_unmap_mii_ctrl:
  14323. + iounmap(ag->mii_ctrl);
  14324. + err_unmap_base:
  14325. + iounmap(ag->mac_base);
  14326. + err_free_dev:
  14327. + kfree(dev);
  14328. + err_out:
  14329. + platform_set_drvdata(pdev, NULL);
  14330. + return err;
  14331. +}
  14332. +
  14333. +static int __exit ag71xx_remove(struct platform_device *pdev)
  14334. +{
  14335. + struct net_device *dev = platform_get_drvdata(pdev);
  14336. +
  14337. + if (dev) {
  14338. + struct ag71xx *ag = netdev_priv(dev);
  14339. +
  14340. + ag71xx_debugfs_exit(ag);
  14341. + ag71xx_phy_disconnect(ag);
  14342. + unregister_netdev(dev);
  14343. + free_irq(dev->irq, dev);
  14344. + iounmap(ag->mii_ctrl);
  14345. + iounmap(ag->mac_base);
  14346. + kfree(dev);
  14347. + platform_set_drvdata(pdev, NULL);
  14348. + }
  14349. +
  14350. + return 0;
  14351. +}
  14352. +
  14353. +static struct platform_driver ag71xx_driver = {
  14354. + .probe = ag71xx_probe,
  14355. + .remove = __exit_p(ag71xx_remove),
  14356. + .driver = {
  14357. + .name = AG71XX_DRV_NAME,
  14358. + }
  14359. +};
  14360. +
  14361. +static int __init ag71xx_module_init(void)
  14362. +{
  14363. + int ret;
  14364. +
  14365. + ret = ag71xx_debugfs_root_init();
  14366. + if (ret)
  14367. + goto err_out;
  14368. +
  14369. + ret = ag71xx_mdio_driver_init();
  14370. + if (ret)
  14371. + goto err_debugfs_exit;
  14372. +
  14373. + ret = platform_driver_register(&ag71xx_driver);
  14374. + if (ret)
  14375. + goto err_mdio_exit;
  14376. +
  14377. + return 0;
  14378. +
  14379. + err_mdio_exit:
  14380. + ag71xx_mdio_driver_exit();
  14381. + err_debugfs_exit:
  14382. + ag71xx_debugfs_root_exit();
  14383. + err_out:
  14384. + return ret;
  14385. +}
  14386. +
  14387. +static void __exit ag71xx_module_exit(void)
  14388. +{
  14389. + platform_driver_unregister(&ag71xx_driver);
  14390. + ag71xx_mdio_driver_exit();
  14391. + ag71xx_debugfs_root_exit();
  14392. +}
  14393. +
  14394. +module_init(ag71xx_module_init);
  14395. +module_exit(ag71xx_module_exit);
  14396. +
  14397. +MODULE_VERSION(AG71XX_DRV_VERSION);
  14398. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  14399. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  14400. +MODULE_LICENSE("GPL v2");
  14401. +MODULE_ALIAS("platform:" AG71XX_DRV_NAME);
  14402. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.36/drivers/net/ag71xx/ag71xx_mdio.c
  14403. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100
  14404. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_mdio.c 2010-12-17 18:34:51.000000000 +0100
  14405. @@ -0,0 +1,243 @@
  14406. +/*
  14407. + * Atheros AR71xx built-in ethernet mac driver
  14408. + *
  14409. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14410. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14411. + *
  14412. + * Based on Atheros' AG7100 driver
  14413. + *
  14414. + * This program is free software; you can redistribute it and/or modify it
  14415. + * under the terms of the GNU General Public License version 2 as published
  14416. + * by the Free Software Foundation.
  14417. + */
  14418. +
  14419. +#include "ag71xx.h"
  14420. +
  14421. +#define AG71XX_MDIO_RETRY 1000
  14422. +#define AG71XX_MDIO_DELAY 5
  14423. +
  14424. +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg,
  14425. + u32 value)
  14426. +{
  14427. + void __iomem *r;
  14428. +
  14429. + r = am->mdio_base + reg;
  14430. + __raw_writel(value, r);
  14431. +
  14432. + /* flush write */
  14433. + (void) __raw_readl(r);
  14434. +}
  14435. +
  14436. +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg)
  14437. +{
  14438. + return __raw_readl(am->mdio_base + reg);
  14439. +}
  14440. +
  14441. +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
  14442. +{
  14443. + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n",
  14444. + am->mii_bus->name,
  14445. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG),
  14446. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD),
  14447. + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR));
  14448. + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n",
  14449. + am->mii_bus->name,
  14450. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL),
  14451. + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS),
  14452. + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
  14453. +}
  14454. +
  14455. +static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
  14456. +{
  14457. + int ret;
  14458. + int i;
  14459. +
  14460. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14461. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14462. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14463. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ);
  14464. +
  14465. + i = AG71XX_MDIO_RETRY;
  14466. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14467. + if (i-- == 0) {
  14468. + printk(KERN_ERR "%s: mii_read timed out\n",
  14469. + am->mii_bus->name);
  14470. + ret = 0xffff;
  14471. + goto out;
  14472. + }
  14473. + udelay(AG71XX_MDIO_DELAY);
  14474. + }
  14475. +
  14476. + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff;
  14477. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14478. +
  14479. + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
  14480. +
  14481. + out:
  14482. + return ret;
  14483. +}
  14484. +
  14485. +static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am,
  14486. + int addr, int reg, u16 val)
  14487. +{
  14488. + int i;
  14489. +
  14490. + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
  14491. +
  14492. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14493. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14494. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val);
  14495. +
  14496. + i = AG71XX_MDIO_RETRY;
  14497. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14498. + if (i-- == 0) {
  14499. + printk(KERN_ERR "%s: mii_write timed out\n",
  14500. + am->mii_bus->name);
  14501. + break;
  14502. + }
  14503. + udelay(AG71XX_MDIO_DELAY);
  14504. + }
  14505. +}
  14506. +
  14507. +static int ag71xx_mdio_reset(struct mii_bus *bus)
  14508. +{
  14509. + struct ag71xx_mdio *am = bus->priv;
  14510. + u32 t;
  14511. +
  14512. + if (am->pdata->is_ar7240)
  14513. + t = MII_CFG_CLK_DIV_6;
  14514. + else
  14515. + t = MII_CFG_CLK_DIV_28;
  14516. +
  14517. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
  14518. + udelay(100);
  14519. +
  14520. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t);
  14521. + udelay(100);
  14522. +
  14523. + return 0;
  14524. +}
  14525. +
  14526. +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
  14527. +{
  14528. + struct ag71xx_mdio *am = bus->priv;
  14529. +
  14530. + return ag71xx_mdio_mii_read(am, addr, reg);
  14531. +}
  14532. +
  14533. +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
  14534. +{
  14535. + struct ag71xx_mdio *am = bus->priv;
  14536. +
  14537. + ag71xx_mdio_mii_write(am, addr, reg, val);
  14538. + return 0;
  14539. +}
  14540. +
  14541. +static int __init ag71xx_mdio_probe(struct platform_device *pdev)
  14542. +{
  14543. + struct ag71xx_mdio_platform_data *pdata;
  14544. + struct ag71xx_mdio *am;
  14545. + struct resource *res;
  14546. + int i;
  14547. + int err;
  14548. +
  14549. + pdata = pdev->dev.platform_data;
  14550. + if (!pdata) {
  14551. + dev_err(&pdev->dev, "no platform data specified\n");
  14552. + return -EINVAL;
  14553. + }
  14554. +
  14555. + am = kzalloc(sizeof(*am), GFP_KERNEL);
  14556. + if (!am) {
  14557. + err = -ENOMEM;
  14558. + goto err_out;
  14559. + }
  14560. +
  14561. + am->pdata = pdata;
  14562. +
  14563. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  14564. + if (!res) {
  14565. + dev_err(&pdev->dev, "no iomem resource found\n");
  14566. + err = -ENXIO;
  14567. + goto err_out;
  14568. + }
  14569. +
  14570. + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14571. + if (!am->mdio_base) {
  14572. + dev_err(&pdev->dev, "unable to ioremap registers\n");
  14573. + err = -ENOMEM;
  14574. + goto err_free_mdio;
  14575. + }
  14576. +
  14577. + am->mii_bus = mdiobus_alloc();
  14578. + if (am->mii_bus == NULL) {
  14579. + err = -ENOMEM;
  14580. + goto err_iounmap;
  14581. + }
  14582. +
  14583. + am->mii_bus->name = "ag71xx_mdio";
  14584. + am->mii_bus->read = ag71xx_mdio_read;
  14585. + am->mii_bus->write = ag71xx_mdio_write;
  14586. + am->mii_bus->reset = ag71xx_mdio_reset;
  14587. + am->mii_bus->irq = am->mii_irq;
  14588. + am->mii_bus->priv = am;
  14589. + am->mii_bus->parent = &pdev->dev;
  14590. + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
  14591. + am->mii_bus->phy_mask = pdata->phy_mask;
  14592. +
  14593. + for (i = 0; i < PHY_MAX_ADDR; i++)
  14594. + am->mii_irq[i] = PHY_POLL;
  14595. +
  14596. + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0);
  14597. +
  14598. + err = mdiobus_register(am->mii_bus);
  14599. + if (err)
  14600. + goto err_free_bus;
  14601. +
  14602. + ag71xx_mdio_dump_regs(am);
  14603. +
  14604. + platform_set_drvdata(pdev, am);
  14605. + return 0;
  14606. +
  14607. + err_free_bus:
  14608. + mdiobus_free(am->mii_bus);
  14609. + err_iounmap:
  14610. + iounmap(am->mdio_base);
  14611. + err_free_mdio:
  14612. + kfree(am);
  14613. + err_out:
  14614. + return err;
  14615. +}
  14616. +
  14617. +static int __exit ag71xx_mdio_remove(struct platform_device *pdev)
  14618. +{
  14619. + struct ag71xx_mdio *am = platform_get_drvdata(pdev);
  14620. +
  14621. + if (am) {
  14622. + mdiobus_unregister(am->mii_bus);
  14623. + mdiobus_free(am->mii_bus);
  14624. + iounmap(am->mdio_base);
  14625. + kfree(am);
  14626. + platform_set_drvdata(pdev, NULL);
  14627. + }
  14628. +
  14629. + return 0;
  14630. +}
  14631. +
  14632. +static struct platform_driver ag71xx_mdio_driver = {
  14633. + .probe = ag71xx_mdio_probe,
  14634. + .remove = __exit_p(ag71xx_mdio_remove),
  14635. + .driver = {
  14636. + .name = "ag71xx-mdio",
  14637. + }
  14638. +};
  14639. +
  14640. +int ag71xx_mdio_driver_init(void)
  14641. +{
  14642. + return platform_driver_register(&ag71xx_mdio_driver);
  14643. +}
  14644. +
  14645. +void ag71xx_mdio_driver_exit(void)
  14646. +{
  14647. + platform_driver_unregister(&ag71xx_mdio_driver);
  14648. +}
  14649. diff -Nur linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.36/drivers/net/ag71xx/ag71xx_phy.c
  14650. --- linux-2.6.36.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100
  14651. +++ linux-2.6.36/drivers/net/ag71xx/ag71xx_phy.c 2010-12-17 18:34:51.000000000 +0100
  14652. @@ -0,0 +1,213 @@
  14653. +/*
  14654. + * Atheros AR71xx built-in ethernet mac driver
  14655. + *
  14656. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14657. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14658. + *
  14659. + * Based on Atheros' AG7100 driver
  14660. + *
  14661. + * This program is free software; you can redistribute it and/or modify it
  14662. + * under the terms of the GNU General Public License version 2 as published
  14663. + * by the Free Software Foundation.
  14664. + */
  14665. +
  14666. +#include "ag71xx.h"
  14667. +
  14668. +static void ag71xx_phy_link_adjust(struct net_device *dev)
  14669. +{
  14670. + struct ag71xx *ag = netdev_priv(dev);
  14671. + struct phy_device *phydev = ag->phy_dev;
  14672. + unsigned long flags;
  14673. + int status_change = 0;
  14674. +
  14675. + spin_lock_irqsave(&ag->lock, flags);
  14676. +
  14677. + if (phydev->link) {
  14678. + if (ag->duplex != phydev->duplex
  14679. + || ag->speed != phydev->speed) {
  14680. + status_change = 1;
  14681. + }
  14682. + }
  14683. +
  14684. + if (phydev->link != ag->link)
  14685. + status_change = 1;
  14686. +
  14687. + ag->link = phydev->link;
  14688. + ag->duplex = phydev->duplex;
  14689. + ag->speed = phydev->speed;
  14690. +
  14691. + if (status_change)
  14692. + ag71xx_link_adjust(ag);
  14693. +
  14694. + spin_unlock_irqrestore(&ag->lock, flags);
  14695. +}
  14696. +
  14697. +void ag71xx_phy_start(struct ag71xx *ag)
  14698. +{
  14699. + if (ag->phy_dev) {
  14700. + phy_start(ag->phy_dev);
  14701. + } else {
  14702. + ag->link = 1;
  14703. + ag71xx_link_adjust(ag);
  14704. + }
  14705. +}
  14706. +
  14707. +void ag71xx_phy_stop(struct ag71xx *ag)
  14708. +{
  14709. + if (ag->phy_dev) {
  14710. + phy_stop(ag->phy_dev);
  14711. + } else {
  14712. + ag->link = 0;
  14713. + ag71xx_link_adjust(ag);
  14714. + }
  14715. +}
  14716. +
  14717. +static int ag71xx_phy_connect_fixed(struct ag71xx *ag)
  14718. +{
  14719. + struct net_device *dev = ag->dev;
  14720. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14721. + int ret = 0;
  14722. +
  14723. + /* use fixed settings */
  14724. + switch (pdata->speed) {
  14725. + case SPEED_10:
  14726. + case SPEED_100:
  14727. + case SPEED_1000:
  14728. + break;
  14729. + default:
  14730. + printk(KERN_ERR "%s: invalid speed specified\n", dev->name);
  14731. + ret = -EINVAL;
  14732. + break;
  14733. + }
  14734. +
  14735. + printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name);
  14736. +
  14737. + ag->duplex = pdata->duplex;
  14738. + ag->speed = pdata->speed;
  14739. +
  14740. + return ret;
  14741. +}
  14742. +
  14743. +static int ag71xx_phy_connect_multi(struct ag71xx *ag)
  14744. +{
  14745. + struct net_device *dev = ag->dev;
  14746. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14747. + struct phy_device *phydev = NULL;
  14748. + int phy_addr;
  14749. + int ret = 0;
  14750. +
  14751. + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
  14752. + if (!(pdata->phy_mask & (1 << phy_addr)))
  14753. + continue;
  14754. +
  14755. + if (ag->mii_bus->phy_map[phy_addr] == NULL)
  14756. + continue;
  14757. +
  14758. + DBG("%s: PHY found at %s, uid=%08x\n",
  14759. + dev->name,
  14760. + dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),
  14761. + ag->mii_bus->phy_map[phy_addr]->phy_id);
  14762. +
  14763. + if (phydev == NULL)
  14764. + phydev = ag->mii_bus->phy_map[phy_addr];
  14765. + }
  14766. +
  14767. + if (!phydev) {
  14768. + printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",
  14769. + dev->name, pdata->phy_mask);
  14770. + return -ENODEV;
  14771. + }
  14772. +
  14773. + ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev),
  14774. + &ag71xx_phy_link_adjust, 0,
  14775. + pdata->phy_if_mode);
  14776. +
  14777. + if (IS_ERR(ag->phy_dev)) {
  14778. + printk(KERN_ERR "%s: could not connect to PHY at %s\n",
  14779. + dev->name, dev_name(&phydev->dev));
  14780. + return PTR_ERR(ag->phy_dev);
  14781. + }
  14782. +
  14783. + /* mask with MAC supported features */
  14784. + if (pdata->has_gbit)
  14785. + phydev->supported &= PHY_GBIT_FEATURES;
  14786. + else
  14787. + phydev->supported &= PHY_BASIC_FEATURES;
  14788. +
  14789. + phydev->advertising = phydev->supported;
  14790. +
  14791. + printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
  14792. + dev->name, dev_name(&phydev->dev),
  14793. + phydev->phy_id, phydev->drv->name);
  14794. +
  14795. + ag->link = 0;
  14796. + ag->speed = 0;
  14797. + ag->duplex = -1;
  14798. +
  14799. + return ret;
  14800. +}
  14801. +
  14802. +static int dev_is_class(struct device *dev, void *class)
  14803. +{
  14804. + if (dev->class != NULL && !strcmp(dev->class->name, class))
  14805. + return 1;
  14806. +
  14807. + return 0;
  14808. +}
  14809. +
  14810. +static struct device *dev_find_class(struct device *parent, char *class)
  14811. +{
  14812. + if (dev_is_class(parent, class)) {
  14813. + get_device(parent);
  14814. + return parent;
  14815. + }
  14816. +
  14817. + return device_find_child(parent, class, dev_is_class);
  14818. +}
  14819. +
  14820. +static struct mii_bus *dev_to_mii_bus(struct device *dev)
  14821. +{
  14822. + struct device *d;
  14823. +
  14824. + d = dev_find_class(dev, "mdio_bus");
  14825. + if (d != NULL) {
  14826. + struct mii_bus *bus;
  14827. +
  14828. + bus = to_mii_bus(d);
  14829. + put_device(d);
  14830. +
  14831. + return bus;
  14832. + }
  14833. +
  14834. + return NULL;
  14835. +}
  14836. +
  14837. +int ag71xx_phy_connect(struct ag71xx *ag)
  14838. +{
  14839. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14840. +
  14841. + ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev);
  14842. + if (ag->mii_bus == NULL) {
  14843. + printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n",
  14844. + ag->dev->name, dev_name(pdata->mii_bus_dev));
  14845. + return -ENODEV;
  14846. + }
  14847. +
  14848. + /* Reset the mdio bus explicitly */
  14849. + if (ag->mii_bus->reset) {
  14850. + mutex_lock(&ag->mii_bus->mdio_lock);
  14851. + ag->mii_bus->reset(ag->mii_bus);
  14852. + mutex_unlock(&ag->mii_bus->mdio_lock);
  14853. + }
  14854. +
  14855. + if (pdata->phy_mask)
  14856. + return ag71xx_phy_connect_multi(ag);
  14857. +
  14858. + return ag71xx_phy_connect_fixed(ag);
  14859. +}
  14860. +
  14861. +void ag71xx_phy_disconnect(struct ag71xx *ag)
  14862. +{
  14863. + if (ag->phy_dev)
  14864. + phy_disconnect(ag->phy_dev);
  14865. +}
  14866. diff -Nur linux-2.6.36.orig/drivers/net/phy/Kconfig linux-2.6.36/drivers/net/phy/Kconfig
  14867. --- linux-2.6.36.orig/drivers/net/phy/Kconfig 2010-10-20 22:30:22.000000000 +0200
  14868. +++ linux-2.6.36/drivers/net/phy/Kconfig 2010-12-17 18:34:51.000000000 +0100
  14869. @@ -93,6 +93,10 @@
  14870. ---help---
  14871. Supports the KSZ9021, VSC8201, KS8001 PHYs.
  14872. +config IP175C_PHY
  14873. + tristate "Driver for IC+ IP175C/IP178C switches"
  14874. + select SWCONFIG
  14875. +
  14876. config FIXED_PHY
  14877. bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
  14878. depends on PHYLIB=y
  14879. diff -Nur linux-2.6.36.orig/drivers/net/phy/phy.c linux-2.6.36/drivers/net/phy/phy.c
  14880. --- linux-2.6.36.orig/drivers/net/phy/phy.c 2010-10-20 22:30:22.000000000 +0200
  14881. +++ linux-2.6.36/drivers/net/phy/phy.c 2010-12-17 18:34:51.000000000 +0100
  14882. @@ -298,6 +298,50 @@
  14883. }
  14884. EXPORT_SYMBOL(phy_ethtool_gset);
  14885. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  14886. +{
  14887. + u32 cmd;
  14888. + int tmp;
  14889. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  14890. + struct ethtool_value edata = { ETHTOOL_GLINK };
  14891. +
  14892. + if (get_user(cmd, (u32 *) useraddr))
  14893. + return -EFAULT;
  14894. +
  14895. + switch (cmd) {
  14896. + case ETHTOOL_GSET:
  14897. + phy_ethtool_gset(phydev, &ecmd);
  14898. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  14899. + return -EFAULT;
  14900. + return 0;
  14901. +
  14902. + case ETHTOOL_SSET:
  14903. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  14904. + return -EFAULT;
  14905. + return phy_ethtool_sset(phydev, &ecmd);
  14906. +
  14907. + case ETHTOOL_NWAY_RST:
  14908. + /* if autoneg is off, it's an error */
  14909. + tmp = phy_read(phydev, MII_BMCR);
  14910. + if (tmp & BMCR_ANENABLE) {
  14911. + tmp |= (BMCR_ANRESTART);
  14912. + phy_write(phydev, MII_BMCR, tmp);
  14913. + return 0;
  14914. + }
  14915. + return -EINVAL;
  14916. +
  14917. + case ETHTOOL_GLINK:
  14918. + edata.data = (phy_read(phydev,
  14919. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  14920. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  14921. + return -EFAULT;
  14922. + return 0;
  14923. + }
  14924. +
  14925. + return -EOPNOTSUPP;
  14926. +}
  14927. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  14928. +
  14929. /**
  14930. * phy_mii_ioctl - generic PHY MII ioctl interface
  14931. * @phydev: the phy_device struct
  14932. @@ -352,7 +396,7 @@
  14933. }
  14934. phy_write(phydev, mii_data->reg_num, val);
  14935. -
  14936. +
  14937. if (mii_data->reg_num == MII_BMCR &&
  14938. val & BMCR_RESET &&
  14939. phydev->drv->config_init) {
  14940. @@ -471,7 +515,7 @@
  14941. int idx;
  14942. idx = phy_find_setting(phydev->speed, phydev->duplex);
  14943. -
  14944. +
  14945. idx++;
  14946. idx = phy_find_valid(idx, phydev->supported);
  14947. diff -Nur linux-2.6.36.orig/drivers/net/phy/phy_device.c linux-2.6.36/drivers/net/phy/phy_device.c
  14948. --- linux-2.6.36.orig/drivers/net/phy/phy_device.c 2010-10-20 22:30:22.000000000 +0200
  14949. +++ linux-2.6.36/drivers/net/phy/phy_device.c 2010-12-17 18:34:51.000000000 +0100
  14950. @@ -146,6 +146,18 @@
  14951. }
  14952. EXPORT_SYMBOL(phy_scan_fixups);
  14953. +static int generic_receive_skb(struct sk_buff *skb)
  14954. +{
  14955. + skb->protocol = eth_type_trans(skb, skb->dev);
  14956. + return netif_receive_skb(skb);
  14957. +}
  14958. +
  14959. +static int generic_rx(struct sk_buff *skb)
  14960. +{
  14961. + skb->protocol = eth_type_trans(skb, skb->dev);
  14962. + return netif_rx(skb);
  14963. +}
  14964. +
  14965. struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
  14966. {
  14967. struct phy_device *dev;
  14968. @@ -176,6 +188,8 @@
  14969. dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
  14970. dev->state = PHY_DOWN;
  14971. + dev->netif_receive_skb = &generic_receive_skb;
  14972. + dev->netif_rx = &generic_rx;
  14973. mutex_init(&dev->lock);
  14974. INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
  14975. diff -Nur linux-2.6.36.orig/drivers/spi/Kconfig linux-2.6.36/drivers/spi/Kconfig
  14976. --- linux-2.6.36.orig/drivers/spi/Kconfig 2010-10-20 22:30:22.000000000 +0200
  14977. +++ linux-2.6.36/drivers/spi/Kconfig 2010-12-17 18:34:51.000000000 +0100
  14978. @@ -53,6 +53,13 @@
  14979. comment "SPI Master Controller Drivers"
  14980. +config SPI_AR71XX
  14981. + tristate "Atheros AR71xx SPI Controller"
  14982. + depends on SPI_MASTER && ATHEROS_AR71XX
  14983. + select SPI_BITBANG
  14984. + help
  14985. + This is the SPI contoller driver for Atheros AR71xx.
  14986. +
  14987. config SPI_ATMEL
  14988. tristate "Atmel SPI Controller"
  14989. depends on (ARCH_AT91 || AVR32)
  14990. diff -Nur linux-2.6.36.orig/drivers/spi/Makefile linux-2.6.36/drivers/spi/Makefile
  14991. --- linux-2.6.36.orig/drivers/spi/Makefile 2010-10-20 22:30:22.000000000 +0200
  14992. +++ linux-2.6.36/drivers/spi/Makefile 2010-12-17 18:34:51.000000000 +0100
  14993. @@ -11,6 +11,7 @@
  14994. obj-$(CONFIG_SPI_MASTER) += spi.o
  14995. # SPI master controller drivers (bus)
  14996. +obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
  14997. obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
  14998. obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
  14999. obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
  15000. diff -Nur linux-2.6.36.orig/drivers/spi/ap83_spi.c linux-2.6.36/drivers/spi/ap83_spi.c
  15001. --- linux-2.6.36.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100
  15002. +++ linux-2.6.36/drivers/spi/ap83_spi.c 2010-12-17 18:34:51.000000000 +0100
  15003. @@ -0,0 +1,282 @@
  15004. +/*
  15005. + * Atheros AP83 board specific SPI Controller driver
  15006. + *
  15007. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15008. + *
  15009. + * This program is free software; you can redistribute it and/or modify
  15010. + * it under the terms of the GNU General Public License version 2 as
  15011. + * published by the Free Software Foundation.
  15012. + *
  15013. + */
  15014. +
  15015. +#include <linux/kernel.h>
  15016. +#include <linux/init.h>
  15017. +#include <linux/delay.h>
  15018. +#include <linux/spinlock.h>
  15019. +#include <linux/workqueue.h>
  15020. +#include <linux/platform_device.h>
  15021. +#include <linux/io.h>
  15022. +#include <linux/spi/spi.h>
  15023. +#include <linux/spi/spi_bitbang.h>
  15024. +#include <linux/bitops.h>
  15025. +#include <linux/gpio.h>
  15026. +
  15027. +#include <asm/mach-ar71xx/ar71xx.h>
  15028. +#include <asm/mach-ar71xx/platform.h>
  15029. +
  15030. +#define DRV_DESC "Atheros AP83 board SPI Controller driver"
  15031. +#define DRV_VERSION "0.1.0"
  15032. +#define DRV_NAME "ap83-spi"
  15033. +
  15034. +#define AP83_SPI_CLK_HIGH (1 << 23)
  15035. +#define AP83_SPI_CLK_LOW 0
  15036. +#define AP83_SPI_MOSI_HIGH (1 << 22)
  15037. +#define AP83_SPI_MOSI_LOW 0
  15038. +
  15039. +#define AP83_SPI_GPIO_CS 1
  15040. +#define AP83_SPI_GPIO_MISO 3
  15041. +
  15042. +struct ap83_spi {
  15043. + struct spi_bitbang bitbang;
  15044. + void __iomem *base;
  15045. + u32 addr;
  15046. +
  15047. + struct platform_device *pdev;
  15048. +};
  15049. +
  15050. +static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg)
  15051. +{
  15052. + return __raw_readl(sp->base + reg);
  15053. +}
  15054. +
  15055. +static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi)
  15056. +{
  15057. + return spi_master_get_devdata(spi->master);
  15058. +}
  15059. +
  15060. +static inline void setsck(struct spi_device *spi, int val)
  15061. +{
  15062. + struct ap83_spi *sp = spidev_to_sp(spi);
  15063. +
  15064. + if (val)
  15065. + sp->addr |= AP83_SPI_CLK_HIGH;
  15066. + else
  15067. + sp->addr &= ~AP83_SPI_CLK_HIGH;
  15068. +
  15069. + dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n",
  15070. + sp->addr, (val) ? "HIGH" : "LOW");
  15071. +
  15072. + ap83_spi_rr(sp, sp->addr);
  15073. +}
  15074. +
  15075. +static inline void setmosi(struct spi_device *spi, int val)
  15076. +{
  15077. + struct ap83_spi *sp = spidev_to_sp(spi);
  15078. +
  15079. + if (val)
  15080. + sp->addr |= AP83_SPI_MOSI_HIGH;
  15081. + else
  15082. + sp->addr &= ~AP83_SPI_MOSI_HIGH;
  15083. +
  15084. + dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n",
  15085. + sp->addr, (val) ? "HIGH" : "LOW");
  15086. +
  15087. + ap83_spi_rr(sp, sp->addr);
  15088. +}
  15089. +
  15090. +static inline u32 getmiso(struct spi_device *spi)
  15091. +{
  15092. + u32 ret;
  15093. +
  15094. + ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0;
  15095. + dev_dbg(&spi->dev, "get MISO: %d\n", ret);
  15096. +
  15097. + return ret;
  15098. +}
  15099. +
  15100. +static inline void do_spidelay(struct spi_device *spi, unsigned nsecs)
  15101. +{
  15102. + ndelay(nsecs);
  15103. +}
  15104. +
  15105. +static void ap83_spi_chipselect(struct spi_device *spi, int on)
  15106. +{
  15107. + struct ap83_spi *sp = spidev_to_sp(spi);
  15108. +
  15109. + dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1);
  15110. +
  15111. + if (on) {
  15112. + ar71xx_flash_acquire();
  15113. +
  15114. + sp->addr = 0;
  15115. + ap83_spi_rr(sp, sp->addr);
  15116. +
  15117. + gpio_set_value(AP83_SPI_GPIO_CS, 0);
  15118. + } else {
  15119. + gpio_set_value(AP83_SPI_GPIO_CS, 1);
  15120. + ar71xx_flash_release();
  15121. + }
  15122. +}
  15123. +
  15124. +#define spidelay(nsecs) \
  15125. + do { \
  15126. + /* Steal the spi_device pointer from our caller. \
  15127. + * The bitbang-API should probably get fixed here... */ \
  15128. + do_spidelay(spi, nsecs); \
  15129. + } while (0)
  15130. +
  15131. +#define EXPAND_BITBANG_TXRX
  15132. +#include <linux/spi/spi_bitbang.h>
  15133. +
  15134. +static u32 ap83_spi_txrx_mode0(struct spi_device *spi,
  15135. + unsigned nsecs, u32 word, u8 bits)
  15136. +{
  15137. + dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits);
  15138. + return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
  15139. +}
  15140. +
  15141. +static u32 ap83_spi_txrx_mode1(struct spi_device *spi,
  15142. + unsigned nsecs, u32 word, u8 bits)
  15143. +{
  15144. + dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits);
  15145. + return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
  15146. +}
  15147. +
  15148. +static u32 ap83_spi_txrx_mode2(struct spi_device *spi,
  15149. + unsigned nsecs, u32 word, u8 bits)
  15150. +{
  15151. + dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits);
  15152. + return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
  15153. +}
  15154. +
  15155. +static u32 ap83_spi_txrx_mode3(struct spi_device *spi,
  15156. + unsigned nsecs, u32 word, u8 bits)
  15157. +{
  15158. + dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits);
  15159. + return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
  15160. +}
  15161. +
  15162. +static int ap83_spi_probe(struct platform_device *pdev)
  15163. +{
  15164. + struct spi_master *master;
  15165. + struct ap83_spi *sp;
  15166. + struct ap83_spi_platform_data *pdata;
  15167. + struct resource *r;
  15168. + int ret;
  15169. +
  15170. + ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso");
  15171. + if (ret) {
  15172. + dev_err(&pdev->dev, "gpio request failed for MISO\n");
  15173. + return ret;
  15174. + }
  15175. +
  15176. + ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs");
  15177. + if (ret) {
  15178. + dev_err(&pdev->dev, "gpio request failed for CS\n");
  15179. + goto err_free_miso;
  15180. + }
  15181. +
  15182. + ret = gpio_direction_input(AP83_SPI_GPIO_MISO);
  15183. + if (ret) {
  15184. + dev_err(&pdev->dev, "unable to set direction of MISO\n");
  15185. + goto err_free_cs;
  15186. + }
  15187. +
  15188. + ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0);
  15189. + if (ret) {
  15190. + dev_err(&pdev->dev, "unable to set direction of CS\n");
  15191. + goto err_free_cs;
  15192. + }
  15193. +
  15194. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15195. + if (master == NULL) {
  15196. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15197. + return -ENOMEM;
  15198. + }
  15199. +
  15200. + sp = spi_master_get_devdata(master);
  15201. + platform_set_drvdata(pdev, sp);
  15202. +
  15203. + pdata = pdev->dev.platform_data;
  15204. +
  15205. + sp->bitbang.master = spi_master_get(master);
  15206. + sp->bitbang.chipselect = ap83_spi_chipselect;
  15207. + sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0;
  15208. + sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1;
  15209. + sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2;
  15210. + sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3;
  15211. +
  15212. + sp->bitbang.master->bus_num = pdev->id;
  15213. + sp->bitbang.master->num_chipselect = 1;
  15214. +
  15215. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15216. + if (r == NULL) {
  15217. + ret = -ENOENT;
  15218. + goto err_spi_put;
  15219. + }
  15220. +
  15221. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15222. + if (!sp->base) {
  15223. + ret = -ENXIO;
  15224. + goto err_spi_put;
  15225. + }
  15226. +
  15227. + ret = spi_bitbang_start(&sp->bitbang);
  15228. + if (!ret)
  15229. + goto err_unmap;
  15230. +
  15231. + dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start);
  15232. +
  15233. + return 0;
  15234. +
  15235. + err_unmap:
  15236. + iounmap(sp->base);
  15237. + err_spi_put:
  15238. + platform_set_drvdata(pdev, NULL);
  15239. + spi_master_put(sp->bitbang.master);
  15240. +
  15241. + err_free_cs:
  15242. + gpio_free(AP83_SPI_GPIO_CS);
  15243. + err_free_miso:
  15244. + gpio_free(AP83_SPI_GPIO_MISO);
  15245. + return ret;
  15246. +}
  15247. +
  15248. +static int ap83_spi_remove(struct platform_device *pdev)
  15249. +{
  15250. + struct ap83_spi *sp = platform_get_drvdata(pdev);
  15251. +
  15252. + spi_bitbang_stop(&sp->bitbang);
  15253. + iounmap(sp->base);
  15254. + platform_set_drvdata(pdev, NULL);
  15255. + spi_master_put(sp->bitbang.master);
  15256. +
  15257. + return 0;
  15258. +}
  15259. +
  15260. +static struct platform_driver ap83_spi_drv = {
  15261. + .probe = ap83_spi_probe,
  15262. + .remove = ap83_spi_remove,
  15263. + .driver = {
  15264. + .name = DRV_NAME,
  15265. + .owner = THIS_MODULE,
  15266. + },
  15267. +};
  15268. +
  15269. +static int __init ap83_spi_init(void)
  15270. +{
  15271. + return platform_driver_register(&ap83_spi_drv);
  15272. +}
  15273. +module_init(ap83_spi_init);
  15274. +
  15275. +static void __exit ap83_spi_exit(void)
  15276. +{
  15277. + platform_driver_unregister(&ap83_spi_drv);
  15278. +}
  15279. +module_exit(ap83_spi_exit);
  15280. +
  15281. +MODULE_ALIAS("platform:" DRV_NAME);
  15282. +MODULE_DESCRIPTION(DRV_DESC);
  15283. +MODULE_VERSION(DRV_VERSION);
  15284. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15285. +MODULE_LICENSE("GPL v2");
  15286. diff -Nur linux-2.6.36.orig/drivers/spi/ar71xx_spi.c linux-2.6.36/drivers/spi/ar71xx_spi.c
  15287. --- linux-2.6.36.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  15288. +++ linux-2.6.36/drivers/spi/ar71xx_spi.c 2010-12-17 18:34:51.000000000 +0100
  15289. @@ -0,0 +1,283 @@
  15290. +/*
  15291. + * Atheros AR71xx SPI Controller driver
  15292. + *
  15293. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  15294. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  15295. + *
  15296. + * This program is free software; you can redistribute it and/or modify
  15297. + * it under the terms of the GNU General Public License version 2 as
  15298. + * published by the Free Software Foundation.
  15299. + *
  15300. + */
  15301. +
  15302. +#include <linux/kernel.h>
  15303. +#include <linux/init.h>
  15304. +#include <linux/delay.h>
  15305. +#include <linux/spinlock.h>
  15306. +#include <linux/workqueue.h>
  15307. +#include <linux/platform_device.h>
  15308. +#include <linux/io.h>
  15309. +#include <linux/spi/spi.h>
  15310. +#include <linux/spi/spi_bitbang.h>
  15311. +#include <linux/bitops.h>
  15312. +
  15313. +#include <asm/mach-ar71xx/ar71xx.h>
  15314. +#include <asm/mach-ar71xx/platform.h>
  15315. +
  15316. +#define DRV_DESC "Atheros AR71xx SPI Controller driver"
  15317. +#define DRV_VERSION "0.2.4"
  15318. +#define DRV_NAME "ar71xx-spi"
  15319. +
  15320. +#undef PER_BIT_READ
  15321. +
  15322. +struct ar71xx_spi {
  15323. + struct spi_bitbang bitbang;
  15324. + u32 ioc_base;
  15325. + u32 reg_ctrl;
  15326. +
  15327. + void __iomem *base;
  15328. +
  15329. + struct platform_device *pdev;
  15330. + u32 (*get_ioc_base)(u8 chip_select, int cs_high,
  15331. + int is_on);
  15332. +};
  15333. +
  15334. +static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15335. +{
  15336. + return __raw_readl(sp->base + reg);
  15337. +}
  15338. +
  15339. +static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15340. +{
  15341. + __raw_writel(val, sp->base + reg);
  15342. +}
  15343. +
  15344. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15345. +{
  15346. + return spi_master_get_devdata(spi->master);
  15347. +}
  15348. +
  15349. +static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  15350. +{
  15351. + u32 ret;
  15352. +
  15353. + if (is_on == AR71XX_SPI_CS_INACTIVE)
  15354. + ret = SPI_IOC_CS_ALL;
  15355. + else
  15356. + ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select);
  15357. +
  15358. + return ret;
  15359. +}
  15360. +
  15361. +static void ar71xx_spi_chipselect(struct spi_device *spi, int value)
  15362. +{
  15363. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15364. + void __iomem *base = sp->base;
  15365. + u32 ioc_base;
  15366. +
  15367. + switch (value) {
  15368. + case BITBANG_CS_INACTIVE:
  15369. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15370. + (spi->mode & SPI_CS_HIGH) != 0,
  15371. + AR71XX_SPI_CS_INACTIVE);
  15372. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15373. + break;
  15374. +
  15375. + case BITBANG_CS_ACTIVE:
  15376. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15377. + (spi->mode & SPI_CS_HIGH) != 0,
  15378. + AR71XX_SPI_CS_ACTIVE);
  15379. +
  15380. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15381. + sp->ioc_base = ioc_base;
  15382. + break;
  15383. + }
  15384. +}
  15385. +
  15386. +static void ar71xx_spi_setup_regs(struct spi_device *spi)
  15387. +{
  15388. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15389. +
  15390. + /* enable GPIO mode */
  15391. + ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15392. +
  15393. + /* save CTRL register */
  15394. + sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL);
  15395. +
  15396. + /* TODO: setup speed? */
  15397. + ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15398. +}
  15399. +
  15400. +static void ar71xx_spi_restore_regs(struct spi_device *spi)
  15401. +{
  15402. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15403. +
  15404. + /* restore CTRL register */
  15405. + ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15406. + /* disable GPIO mode */
  15407. + ar71xx_spi_wr(sp, SPI_REG_FS, 0);
  15408. +}
  15409. +
  15410. +static int ar71xx_spi_setup(struct spi_device *spi)
  15411. +{
  15412. + int status;
  15413. +
  15414. + if (spi->bits_per_word > 32)
  15415. + return -EINVAL;
  15416. +
  15417. + if (!spi->controller_state)
  15418. + ar71xx_spi_setup_regs(spi);
  15419. +
  15420. + status = spi_bitbang_setup(spi);
  15421. + if (status && !spi->controller_state)
  15422. + ar71xx_spi_restore_regs(spi);
  15423. +
  15424. + return status;
  15425. +}
  15426. +
  15427. +static void ar71xx_spi_cleanup(struct spi_device *spi)
  15428. +{
  15429. + ar71xx_spi_restore_regs(spi);
  15430. + spi_bitbang_cleanup(spi);
  15431. +}
  15432. +
  15433. +static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15434. + u32 word, u8 bits)
  15435. +{
  15436. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15437. + void __iomem *base = sp->base;
  15438. + u32 ioc = sp->ioc_base;
  15439. + u32 ret;
  15440. +
  15441. + /* clock starts at inactive polarity */
  15442. + for (word <<= (32 - bits); likely(bits); bits--) {
  15443. + u32 out;
  15444. +
  15445. + if (word & (1 << 31))
  15446. + out = ioc | SPI_IOC_DO;
  15447. + else
  15448. + out = ioc & ~SPI_IOC_DO;
  15449. +
  15450. + /* setup MSB (to slave) on trailing edge */
  15451. + __raw_writel(out, base + SPI_REG_IOC);
  15452. +
  15453. + __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC);
  15454. +
  15455. + word <<= 1;
  15456. +
  15457. +#ifdef PER_BIT_READ
  15458. + /* sample MSB (from slave) on leading edge */
  15459. + ret = __raw_readl(base + SPI_REG_RDS);
  15460. + __raw_writel(out, base + SPI_REG_IOC);
  15461. +#endif
  15462. +
  15463. + }
  15464. +
  15465. +#ifndef PER_BIT_READ
  15466. + ret = __raw_readl(base + SPI_REG_RDS);
  15467. +#endif
  15468. + return ret;
  15469. +}
  15470. +
  15471. +static int ar71xx_spi_probe(struct platform_device *pdev)
  15472. +{
  15473. + struct spi_master *master;
  15474. + struct ar71xx_spi *sp;
  15475. + struct ar71xx_spi_platform_data *pdata;
  15476. + struct resource *r;
  15477. + int ret;
  15478. +
  15479. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15480. + if (master == NULL) {
  15481. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15482. + return -ENOMEM;
  15483. + }
  15484. +
  15485. + sp = spi_master_get_devdata(master);
  15486. + platform_set_drvdata(pdev, sp);
  15487. +
  15488. + pdata = pdev->dev.platform_data;
  15489. +
  15490. + master->setup = ar71xx_spi_setup;
  15491. + master->cleanup = ar71xx_spi_cleanup;
  15492. +
  15493. + sp->bitbang.master = spi_master_get(master);
  15494. + sp->bitbang.chipselect = ar71xx_spi_chipselect;
  15495. + sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
  15496. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15497. +
  15498. + sp->get_ioc_base = ar71xx_spi_get_ioc_base;
  15499. + if (pdata) {
  15500. + sp->bitbang.master->bus_num = pdata->bus_num;
  15501. + sp->bitbang.master->num_chipselect = pdata->num_chipselect;
  15502. + if (pdata->get_ioc_base)
  15503. + sp->get_ioc_base = pdata->get_ioc_base;
  15504. + } else {
  15505. + sp->bitbang.master->bus_num = 0;
  15506. + sp->bitbang.master->num_chipselect = 3;
  15507. + }
  15508. +
  15509. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15510. + if (r == NULL) {
  15511. + ret = -ENOENT;
  15512. + goto err1;
  15513. + }
  15514. +
  15515. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15516. + if (!sp->base) {
  15517. + ret = -ENXIO;
  15518. + goto err1;
  15519. + }
  15520. +
  15521. + ret = spi_bitbang_start(&sp->bitbang);
  15522. + if (!ret)
  15523. + return 0;
  15524. +
  15525. + iounmap(sp->base);
  15526. + err1:
  15527. + platform_set_drvdata(pdev, NULL);
  15528. + spi_master_put(sp->bitbang.master);
  15529. +
  15530. + return ret;
  15531. +}
  15532. +
  15533. +static int ar71xx_spi_remove(struct platform_device *pdev)
  15534. +{
  15535. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15536. +
  15537. + spi_bitbang_stop(&sp->bitbang);
  15538. + iounmap(sp->base);
  15539. + platform_set_drvdata(pdev, NULL);
  15540. + spi_master_put(sp->bitbang.master);
  15541. +
  15542. + return 0;
  15543. +}
  15544. +
  15545. +static struct platform_driver ar71xx_spi_drv = {
  15546. + .probe = ar71xx_spi_probe,
  15547. + .remove = ar71xx_spi_remove,
  15548. + .driver = {
  15549. + .name = DRV_NAME,
  15550. + .owner = THIS_MODULE,
  15551. + },
  15552. +};
  15553. +
  15554. +static int __init ar71xx_spi_init(void)
  15555. +{
  15556. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  15557. + return platform_driver_register(&ar71xx_spi_drv);
  15558. +}
  15559. +module_init(ar71xx_spi_init);
  15560. +
  15561. +static void __exit ar71xx_spi_exit(void)
  15562. +{
  15563. + platform_driver_unregister(&ar71xx_spi_drv);
  15564. +}
  15565. +module_exit(ar71xx_spi_exit);
  15566. +
  15567. +MODULE_ALIAS("platform:" DRV_NAME);
  15568. +MODULE_DESCRIPTION(DRV_DESC);
  15569. +MODULE_VERSION(DRV_VERSION);
  15570. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15571. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  15572. +MODULE_LICENSE("GPL v2");
  15573. diff -Nur linux-2.6.36.orig/drivers/spi/pb44_spi.c linux-2.6.36/drivers/spi/pb44_spi.c
  15574. --- linux-2.6.36.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100
  15575. +++ linux-2.6.36/drivers/spi/pb44_spi.c 2010-12-17 18:34:51.000000000 +0100
  15576. @@ -0,0 +1,299 @@
  15577. +/*
  15578. + * Atheros PB44 board SPI controller driver
  15579. + *
  15580. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15581. + *
  15582. + * This program is free software; you can redistribute it and/or modify
  15583. + * it under the terms of the GNU General Public License version 2 as
  15584. + * published by the Free Software Foundation.
  15585. + *
  15586. + */
  15587. +
  15588. +#include <linux/kernel.h>
  15589. +#include <linux/init.h>
  15590. +#include <linux/delay.h>
  15591. +#include <linux/spinlock.h>
  15592. +#include <linux/workqueue.h>
  15593. +#include <linux/platform_device.h>
  15594. +#include <linux/io.h>
  15595. +#include <linux/spi/spi.h>
  15596. +#include <linux/spi/spi_bitbang.h>
  15597. +#include <linux/bitops.h>
  15598. +#include <linux/gpio.h>
  15599. +
  15600. +#include <asm/mach-ar71xx/ar71xx.h>
  15601. +#include <asm/mach-ar71xx/platform.h>
  15602. +
  15603. +#define DRV_DESC "Atheros PB44 SPI Controller driver"
  15604. +#define DRV_VERSION "0.1.0"
  15605. +#define DRV_NAME "pb44-spi"
  15606. +
  15607. +#undef PER_BIT_READ
  15608. +
  15609. +struct ar71xx_spi {
  15610. + struct spi_bitbang bitbang;
  15611. + u32 ioc_base;
  15612. + u32 reg_ctrl;
  15613. +
  15614. + void __iomem *base;
  15615. +
  15616. + struct platform_device *pdev;
  15617. +};
  15618. +
  15619. +static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15620. +{
  15621. + return __raw_readl(sp->base + reg);
  15622. +}
  15623. +
  15624. +static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15625. +{
  15626. + __raw_writel(val, sp->base + reg);
  15627. +}
  15628. +
  15629. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15630. +{
  15631. + return spi_master_get_devdata(spi->master);
  15632. +}
  15633. +
  15634. +static void pb44_spi_chipselect(struct spi_device *spi, int is_active)
  15635. +{
  15636. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15637. + int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
  15638. +
  15639. + if (is_active) {
  15640. + /* set initial clock polarity */
  15641. + if (spi->mode & SPI_CPOL)
  15642. + sp->ioc_base |= SPI_IOC_CLK;
  15643. + else
  15644. + sp->ioc_base &= ~SPI_IOC_CLK;
  15645. +
  15646. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15647. + }
  15648. +
  15649. + if (spi->chip_select) {
  15650. + unsigned long gpio = (unsigned long) spi->controller_data;
  15651. +
  15652. + /* SPI is normally active-low */
  15653. + gpio_set_value(gpio, cs_high);
  15654. + } else {
  15655. + if (cs_high)
  15656. + sp->ioc_base |= SPI_IOC_CS0;
  15657. + else
  15658. + sp->ioc_base &= ~SPI_IOC_CS0;
  15659. +
  15660. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15661. + }
  15662. +
  15663. +}
  15664. +
  15665. +static int pb44_spi_setup_cs(struct spi_device *spi)
  15666. +{
  15667. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15668. +
  15669. + /* enable GPIO mode */
  15670. + pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15671. +
  15672. + /* save CTRL register */
  15673. + sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL);
  15674. + sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC);
  15675. +
  15676. + /* TODO: setup speed? */
  15677. + pb44_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15678. +
  15679. + if (spi->chip_select) {
  15680. + unsigned long gpio = (unsigned long) spi->controller_data;
  15681. + int status = 0;
  15682. +
  15683. + status = gpio_request(gpio, dev_name(&spi->dev));
  15684. + if (status)
  15685. + return status;
  15686. +
  15687. + status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
  15688. + if (status) {
  15689. + gpio_free(gpio);
  15690. + return status;
  15691. + }
  15692. + } else {
  15693. + if (spi->mode & SPI_CS_HIGH)
  15694. + sp->ioc_base |= SPI_IOC_CS0;
  15695. + else
  15696. + sp->ioc_base &= ~SPI_IOC_CS0;
  15697. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15698. + }
  15699. +
  15700. + return 0;
  15701. +}
  15702. +
  15703. +static void pb44_spi_cleanup_cs(struct spi_device *spi)
  15704. +{
  15705. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15706. +
  15707. + if (spi->chip_select) {
  15708. + unsigned long gpio = (unsigned long) spi->controller_data;
  15709. + gpio_free(gpio);
  15710. + }
  15711. +
  15712. + /* restore CTRL register */
  15713. + pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15714. + /* disable GPIO mode */
  15715. + pb44_spi_wr(sp, SPI_REG_FS, 0);
  15716. +}
  15717. +
  15718. +static int pb44_spi_setup(struct spi_device *spi)
  15719. +{
  15720. + int status = 0;
  15721. +
  15722. + if (spi->bits_per_word > 32)
  15723. + return -EINVAL;
  15724. +
  15725. + if (!spi->controller_state) {
  15726. + status = pb44_spi_setup_cs(spi);
  15727. + if (status)
  15728. + return status;
  15729. + }
  15730. +
  15731. + status = spi_bitbang_setup(spi);
  15732. + if (status && !spi->controller_state)
  15733. + pb44_spi_cleanup_cs(spi);
  15734. +
  15735. + return status;
  15736. +}
  15737. +
  15738. +static void pb44_spi_cleanup(struct spi_device *spi)
  15739. +{
  15740. + pb44_spi_cleanup_cs(spi);
  15741. + spi_bitbang_cleanup(spi);
  15742. +}
  15743. +
  15744. +static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15745. + u32 word, u8 bits)
  15746. +{
  15747. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15748. + u32 ioc = sp->ioc_base;
  15749. + u32 ret;
  15750. +
  15751. + /* clock starts at inactive polarity */
  15752. + for (word <<= (32 - bits); likely(bits); bits--) {
  15753. + u32 out;
  15754. +
  15755. + if (word & (1 << 31))
  15756. + out = ioc | SPI_IOC_DO;
  15757. + else
  15758. + out = ioc & ~SPI_IOC_DO;
  15759. +
  15760. + /* setup MSB (to slave) on trailing edge */
  15761. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15762. + pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK);
  15763. +
  15764. + word <<= 1;
  15765. +
  15766. +#ifdef PER_BIT_READ
  15767. + /* sample MSB (from slave) on leading edge */
  15768. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15769. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15770. +#endif
  15771. + }
  15772. +
  15773. +#ifndef PER_BIT_READ
  15774. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15775. +#endif
  15776. + return ret;
  15777. +}
  15778. +
  15779. +static int pb44_spi_probe(struct platform_device *pdev)
  15780. +{
  15781. + struct spi_master *master;
  15782. + struct ar71xx_spi *sp;
  15783. + struct ar71xx_spi_platform_data *pdata;
  15784. + struct resource *r;
  15785. + int ret;
  15786. +
  15787. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15788. + if (master == NULL) {
  15789. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15790. + return -ENOMEM;
  15791. + }
  15792. +
  15793. + sp = spi_master_get_devdata(master);
  15794. + platform_set_drvdata(pdev, sp);
  15795. +
  15796. + pdata = pdev->dev.platform_data;
  15797. +
  15798. + master->setup = pb44_spi_setup;
  15799. + master->cleanup = pb44_spi_cleanup;
  15800. + if (pdata) {
  15801. + master->bus_num = pdata->bus_num;
  15802. + master->num_chipselect = pdata->num_chipselect;
  15803. + } else {
  15804. + master->bus_num = 0;
  15805. + master->num_chipselect = 1;
  15806. + }
  15807. +
  15808. + sp->bitbang.master = spi_master_get(master);
  15809. + sp->bitbang.chipselect = pb44_spi_chipselect;
  15810. + sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0;
  15811. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15812. + sp->bitbang.flags = SPI_CS_HIGH;
  15813. +
  15814. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15815. + if (r == NULL) {
  15816. + ret = -ENOENT;
  15817. + goto err1;
  15818. + }
  15819. +
  15820. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15821. + if (!sp->base) {
  15822. + ret = -ENXIO;
  15823. + goto err1;
  15824. + }
  15825. +
  15826. + ret = spi_bitbang_start(&sp->bitbang);
  15827. + if (!ret)
  15828. + return 0;
  15829. +
  15830. + iounmap(sp->base);
  15831. + err1:
  15832. + platform_set_drvdata(pdev, NULL);
  15833. + spi_master_put(sp->bitbang.master);
  15834. +
  15835. + return ret;
  15836. +}
  15837. +
  15838. +static int pb44_spi_remove(struct platform_device *pdev)
  15839. +{
  15840. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15841. +
  15842. + spi_bitbang_stop(&sp->bitbang);
  15843. + iounmap(sp->base);
  15844. + platform_set_drvdata(pdev, NULL);
  15845. + spi_master_put(sp->bitbang.master);
  15846. +
  15847. + return 0;
  15848. +}
  15849. +
  15850. +static struct platform_driver pb44_spi_drv = {
  15851. + .probe = pb44_spi_probe,
  15852. + .remove = pb44_spi_remove,
  15853. + .driver = {
  15854. + .name = DRV_NAME,
  15855. + .owner = THIS_MODULE,
  15856. + },
  15857. +};
  15858. +
  15859. +static int __init pb44_spi_init(void)
  15860. +{
  15861. + return platform_driver_register(&pb44_spi_drv);
  15862. +}
  15863. +module_init(pb44_spi_init);
  15864. +
  15865. +static void __exit pb44_spi_exit(void)
  15866. +{
  15867. + platform_driver_unregister(&pb44_spi_drv);
  15868. +}
  15869. +module_exit(pb44_spi_exit);
  15870. +
  15871. +MODULE_ALIAS("platform:" DRV_NAME);
  15872. +MODULE_DESCRIPTION(DRV_DESC);
  15873. +MODULE_VERSION(DRV_VERSION);
  15874. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15875. +MODULE_LICENSE("GPL v2");
  15876. diff -Nur linux-2.6.36.orig/drivers/spi/spi_vsc7385.c linux-2.6.36/drivers/spi/spi_vsc7385.c
  15877. --- linux-2.6.36.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100
  15878. +++ linux-2.6.36/drivers/spi/spi_vsc7385.c 2010-12-17 18:34:51.000000000 +0100
  15879. @@ -0,0 +1,620 @@
  15880. +/*
  15881. + * SPI driver for the Vitesse VSC7385 ethernet switch
  15882. + *
  15883. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15884. + *
  15885. + * Parts of this file are based on Atheros' 2.6.15 BSP
  15886. + *
  15887. + * This program is free software; you can redistribute it and/or modify it
  15888. + * under the terms of the GNU General Public License version 2 as published
  15889. + * by the Free Software Foundation.
  15890. + */
  15891. +
  15892. +#include <linux/types.h>
  15893. +#include <linux/kernel.h>
  15894. +#include <linux/init.h>
  15895. +#include <linux/module.h>
  15896. +#include <linux/delay.h>
  15897. +#include <linux/device.h>
  15898. +#include <linux/bitops.h>
  15899. +#include <linux/firmware.h>
  15900. +#include <linux/spi/spi.h>
  15901. +#include <linux/spi/vsc7385.h>
  15902. +
  15903. +#define DRV_NAME "spi-vsc7385"
  15904. +#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver"
  15905. +#define DRV_VERSION "0.1.0"
  15906. +
  15907. +#define VSC73XX_BLOCK_MAC 0x1
  15908. +#define VSC73XX_BLOCK_2 0x2
  15909. +#define VSC73XX_BLOCK_MII 0x3
  15910. +#define VSC73XX_BLOCK_4 0x4
  15911. +#define VSC73XX_BLOCK_5 0x5
  15912. +#define VSC73XX_BLOCK_SYSTEM 0x7
  15913. +
  15914. +#define VSC73XX_SUBBLOCK_PORT_0 0
  15915. +#define VSC73XX_SUBBLOCK_PORT_1 1
  15916. +#define VSC73XX_SUBBLOCK_PORT_2 2
  15917. +#define VSC73XX_SUBBLOCK_PORT_3 3
  15918. +#define VSC73XX_SUBBLOCK_PORT_4 4
  15919. +#define VSC73XX_SUBBLOCK_PORT_MAC 6
  15920. +
  15921. +/* MAC Block registers */
  15922. +#define VSC73XX_MAC_CFG 0x0
  15923. +#define VSC73XX_ADVPORTM 0x19
  15924. +#define VSC73XX_RXOCT 0x50
  15925. +#define VSC73XX_TXOCT 0x51
  15926. +#define VSC73XX_C_RX0 0x52
  15927. +#define VSC73XX_C_RX1 0x53
  15928. +#define VSC73XX_C_RX2 0x54
  15929. +#define VSC73XX_C_TX0 0x55
  15930. +#define VSC73XX_C_TX1 0x56
  15931. +#define VSC73XX_C_TX2 0x57
  15932. +#define VSC73XX_C_CFG 0x58
  15933. +
  15934. +/* MAC_CFG register bits */
  15935. +#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31)
  15936. +#define VSC73XX_MAC_CFG_PORT_RST (1 << 29)
  15937. +#define VSC73XX_MAC_CFG_TX_EN (1 << 28)
  15938. +#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27)
  15939. +#define VSC73XX_MAC_CFG_FDX (1 << 18)
  15940. +#define VSC73XX_MAC_CFG_GIGE (1 << 17)
  15941. +#define VSC73XX_MAC_CFG_RX_EN (1 << 16)
  15942. +#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15)
  15943. +#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14)
  15944. +#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13)
  15945. +#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6)
  15946. +#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5)
  15947. +#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4)
  15948. +#define VSC73XX_MAC_CFG_BIT2 (1 << 2)
  15949. +#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3)
  15950. +
  15951. +/* ADVPORTM register bits */
  15952. +#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7)
  15953. +#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6)
  15954. +#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5)
  15955. +#define VSC73XX_ADVPORTM_INV_GTX (1 << 4)
  15956. +#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3)
  15957. +#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2)
  15958. +#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1)
  15959. +#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0)
  15960. +
  15961. +/* MII Block registers */
  15962. +#define VSC73XX_MII_STAT 0x0
  15963. +#define VSC73XX_MII_CMD 0x1
  15964. +#define VSC73XX_MII_DATA 0x2
  15965. +
  15966. +/* System Block registers */
  15967. +#define VSC73XX_ICPU_SIPAD 0x01
  15968. +#define VSC73XX_ICPU_CLOCK_DELAY 0x05
  15969. +#define VSC73XX_ICPU_CTRL 0x10
  15970. +#define VSC73XX_ICPU_ADDR 0x11
  15971. +#define VSC73XX_ICPU_SRAM 0x12
  15972. +#define VSC73XX_ICPU_MBOX_VAL 0x15
  15973. +#define VSC73XX_ICPU_MBOX_SET 0x16
  15974. +#define VSC73XX_ICPU_MBOX_CLR 0x17
  15975. +#define VSC73XX_ICPU_CHIPID 0x18
  15976. +#define VSC73XX_ICPU_GPIO 0x34
  15977. +
  15978. +#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8)
  15979. +#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7)
  15980. +#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3)
  15981. +#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2)
  15982. +#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1)
  15983. +#define VSC73XX_ICPU_CTRL_SRST (1 << 0)
  15984. +
  15985. +#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12
  15986. +#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff
  15987. +#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28
  15988. +#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf
  15989. +#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385
  15990. +#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395
  15991. +
  15992. +#define VSC73XX_CMD_MODE_READ 0
  15993. +#define VSC73XX_CMD_MODE_WRITE 1
  15994. +#define VSC73XX_CMD_MODE_SHIFT 4
  15995. +#define VSC73XX_CMD_BLOCK_SHIFT 5
  15996. +#define VSC73XX_CMD_BLOCK_MASK 0x7
  15997. +#define VSC73XX_CMD_SUBBLOCK_MASK 0xf
  15998. +
  15999. +#define VSC7385_CLOCK_DELAY ((3 << 4) | 3)
  16000. +#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3)
  16001. +
  16002. +#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \
  16003. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  16004. + VSC73XX_ICPU_CTRL_EXT_ACC_EN)
  16005. +
  16006. +#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \
  16007. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  16008. + VSC73XX_ICPU_CTRL_CLK_EN | \
  16009. + VSC73XX_ICPU_CTRL_SRST)
  16010. +
  16011. +#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \
  16012. + VSC73XX_ADVPORTM_EXC_COL_CONT | \
  16013. + VSC73XX_ADVPORTM_EXT_PORT | \
  16014. + VSC73XX_ADVPORTM_INV_GTX | \
  16015. + VSC73XX_ADVPORTM_ENA_GTX | \
  16016. + VSC73XX_ADVPORTM_DDR_MODE | \
  16017. + VSC73XX_ADVPORTM_IO_LOOPBACK | \
  16018. + VSC73XX_ADVPORTM_HOST_LOOPBACK)
  16019. +
  16020. +#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \
  16021. + VSC73XX_ADVPORTM_ENA_GTX | \
  16022. + VSC73XX_ADVPORTM_DDR_MODE)
  16023. +
  16024. +#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \
  16025. + VSC73XX_MAC_CFG_MAC_RX_RST | \
  16026. + VSC73XX_MAC_CFG_MAC_TX_RST)
  16027. +
  16028. +#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \
  16029. + VSC73XX_MAC_CFG_FDX | \
  16030. + VSC73XX_MAC_CFG_GIGE | \
  16031. + VSC73XX_MAC_CFG_RX_EN)
  16032. +
  16033. +#define VSC73XX_RESET_DELAY 100
  16034. +
  16035. +struct vsc7385 {
  16036. + struct spi_device *spi;
  16037. + struct mutex lock;
  16038. + struct vsc7385_platform_data *pdata;
  16039. +};
  16040. +
  16041. +static int vsc7385_is_addr_valid(u8 block, u8 subblock)
  16042. +{
  16043. + switch (block) {
  16044. + case VSC73XX_BLOCK_MAC:
  16045. + switch (subblock) {
  16046. + case 0 ... 4:
  16047. + case 6:
  16048. + return 1;
  16049. + }
  16050. + break;
  16051. +
  16052. + case VSC73XX_BLOCK_2:
  16053. + case VSC73XX_BLOCK_SYSTEM:
  16054. + switch (subblock) {
  16055. + case 0:
  16056. + return 1;
  16057. + }
  16058. + break;
  16059. +
  16060. + case VSC73XX_BLOCK_MII:
  16061. + case VSC73XX_BLOCK_4:
  16062. + case VSC73XX_BLOCK_5:
  16063. + switch (subblock) {
  16064. + case 0 ... 1:
  16065. + return 1;
  16066. + }
  16067. + break;
  16068. + }
  16069. +
  16070. + return 0;
  16071. +}
  16072. +
  16073. +static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock)
  16074. +{
  16075. + u8 ret;
  16076. +
  16077. + ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT;
  16078. + ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT;
  16079. + ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK;
  16080. +
  16081. + return ret;
  16082. +}
  16083. +
  16084. +static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  16085. + u32 *value)
  16086. +{
  16087. + u8 cmd[4];
  16088. + u8 buf[4];
  16089. + struct spi_transfer t[2];
  16090. + struct spi_message m;
  16091. + int err;
  16092. +
  16093. + if (!vsc7385_is_addr_valid(block, subblock))
  16094. + return -EINVAL;
  16095. +
  16096. + spi_message_init(&m);
  16097. +
  16098. + memset(&t, 0, sizeof(t));
  16099. +
  16100. + t[0].tx_buf = cmd;
  16101. + t[0].len = sizeof(cmd);
  16102. + spi_message_add_tail(&t[0], &m);
  16103. +
  16104. + t[1].rx_buf = buf;
  16105. + t[1].len = sizeof(buf);
  16106. + spi_message_add_tail(&t[1], &m);
  16107. +
  16108. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock);
  16109. + cmd[1] = reg;
  16110. + cmd[2] = 0;
  16111. + cmd[3] = 0;
  16112. +
  16113. + mutex_lock(&vsc->lock);
  16114. + err = spi_sync(vsc->spi, &m);
  16115. + mutex_unlock(&vsc->lock);
  16116. +
  16117. + if (err)
  16118. + return err;
  16119. +
  16120. + *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) |
  16121. + (((u32) buf[2]) << 8) | ((u32) buf[3]);
  16122. +
  16123. + return 0;
  16124. +}
  16125. +
  16126. +
  16127. +static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  16128. + u32 value)
  16129. +{
  16130. + u8 cmd[2];
  16131. + u8 buf[4];
  16132. + struct spi_transfer t[2];
  16133. + struct spi_message m;
  16134. + int err;
  16135. +
  16136. + if (!vsc7385_is_addr_valid(block, subblock))
  16137. + return -EINVAL;
  16138. +
  16139. + spi_message_init(&m);
  16140. +
  16141. + memset(&t, 0, sizeof(t));
  16142. +
  16143. + t[0].tx_buf = cmd;
  16144. + t[0].len = sizeof(cmd);
  16145. + spi_message_add_tail(&t[0], &m);
  16146. +
  16147. + t[1].tx_buf = buf;
  16148. + t[1].len = sizeof(buf);
  16149. + spi_message_add_tail(&t[1], &m);
  16150. +
  16151. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock);
  16152. + cmd[1] = reg;
  16153. +
  16154. + buf[0] = (value >> 24) & 0xff;
  16155. + buf[1] = (value >> 16) & 0xff;
  16156. + buf[2] = (value >> 8) & 0xff;
  16157. + buf[3] = value & 0xff;
  16158. +
  16159. + mutex_lock(&vsc->lock);
  16160. + err = spi_sync(vsc->spi, &m);
  16161. + mutex_unlock(&vsc->lock);
  16162. +
  16163. + return err;
  16164. +}
  16165. +
  16166. +static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block,
  16167. + u8 subblock, u8 reg, u32 value,
  16168. + u32 read_mask, u32 read_val)
  16169. +{
  16170. + struct spi_device *spi = vsc->spi;
  16171. + u32 t;
  16172. + int err;
  16173. +
  16174. + err = vsc7385_write(vsc, block, subblock, reg, value);
  16175. + if (err)
  16176. + return err;
  16177. +
  16178. + err = vsc7385_read(vsc, block, subblock, reg, &t);
  16179. + if (err)
  16180. + return err;
  16181. +
  16182. + if ((t & read_mask) != read_val) {
  16183. + dev_err(&spi->dev, "register write error\n");
  16184. + return -EIO;
  16185. + }
  16186. +
  16187. + return 0;
  16188. +}
  16189. +
  16190. +static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val)
  16191. +{
  16192. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16193. + VSC73XX_ICPU_CLOCK_DELAY, val);
  16194. +}
  16195. +
  16196. +static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val)
  16197. +{
  16198. + return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16199. + VSC73XX_ICPU_CLOCK_DELAY, val);
  16200. +}
  16201. +
  16202. +static inline int vsc7385_icpu_stop(struct vsc7385 *vsc)
  16203. +{
  16204. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  16205. + VSC73XX_ICPU_CTRL_STOP);
  16206. +}
  16207. +
  16208. +static inline int vsc7385_icpu_start(struct vsc7385 *vsc)
  16209. +{
  16210. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  16211. + VSC73XX_ICPU_CTRL_START);
  16212. +}
  16213. +
  16214. +static inline int vsc7385_icpu_reset(struct vsc7385 *vsc)
  16215. +{
  16216. + int rc;
  16217. +
  16218. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR,
  16219. + 0x0000);
  16220. + if (rc)
  16221. + dev_err(&vsc->spi->dev,
  16222. + "could not reset microcode, err=%d\n", rc);
  16223. +
  16224. + return rc;
  16225. +}
  16226. +
  16227. +static int vsc7385_upload_ucode(struct vsc7385 *vsc)
  16228. +{
  16229. + struct spi_device *spi = vsc->spi;
  16230. + const struct firmware *firmware;
  16231. + char *ucode_name;
  16232. + unsigned char *dp;
  16233. + unsigned int curVal;
  16234. + int i;
  16235. + int diffs;
  16236. + int rc;
  16237. +
  16238. + ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name
  16239. + : "vsc7385_ucode.bin";
  16240. + rc = request_firmware(&firmware, ucode_name, &spi->dev);
  16241. + if (rc) {
  16242. + dev_err(&spi->dev, "request_firmware failed, err=%d\n",
  16243. + rc);
  16244. + return rc;
  16245. + }
  16246. +
  16247. + rc = vsc7385_icpu_stop(vsc);
  16248. + if (rc)
  16249. + goto out;
  16250. +
  16251. + rc = vsc7385_icpu_reset(vsc);
  16252. + if (rc)
  16253. + goto out;
  16254. +
  16255. + dev_info(&spi->dev, "uploading microcode...\n");
  16256. +
  16257. + dp = (unsigned char *) firmware->data;
  16258. + for (i = 0; i < firmware->size; i++) {
  16259. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16260. + VSC73XX_ICPU_SRAM, *dp++);
  16261. + if (rc) {
  16262. + dev_err(&spi->dev, "could not load microcode, err=%d\n",
  16263. + rc);
  16264. + goto out;
  16265. + }
  16266. + }
  16267. +
  16268. + rc = vsc7385_icpu_reset(vsc);
  16269. + if (rc)
  16270. + goto out;
  16271. +
  16272. + dev_info(&spi->dev, "verifying microcode...\n");
  16273. +
  16274. + dp = (unsigned char *) firmware->data;
  16275. + diffs = 0;
  16276. + for (i = 0; i < firmware->size; i++) {
  16277. + rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16278. + VSC73XX_ICPU_SRAM, &curVal);
  16279. + if (rc) {
  16280. + dev_err(&spi->dev, "could not read microcode %d\n",rc);
  16281. + goto out;
  16282. + }
  16283. +
  16284. + if (curVal > 0xff) {
  16285. + dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n",
  16286. + i, *dp, curVal);
  16287. + rc = -EIO;
  16288. + goto out;
  16289. + }
  16290. +
  16291. + if ((curVal & 0xff) != *dp) {
  16292. + diffs++;
  16293. + dev_err(&spi->dev, "verify error: %04x : %02x %02x\n",
  16294. + i, *dp, curVal);
  16295. +
  16296. + if (diffs > 4)
  16297. + break;
  16298. + }
  16299. + dp++;
  16300. + }
  16301. +
  16302. + if (diffs) {
  16303. + dev_err(&spi->dev, "microcode verification failed\n");
  16304. + rc = -EIO;
  16305. + goto out;
  16306. + }
  16307. +
  16308. + dev_info(&spi->dev, "microcode uploaded\n");
  16309. +
  16310. + rc = vsc7385_icpu_start(vsc);
  16311. +
  16312. + out:
  16313. + release_firmware(firmware);
  16314. + return rc;
  16315. +}
  16316. +
  16317. +static int vsc7385_setup(struct vsc7385 *vsc)
  16318. +{
  16319. + struct vsc7385_platform_data *pdata = vsc->pdata;
  16320. + u32 t;
  16321. + int err;
  16322. +
  16323. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16324. + VSC73XX_ICPU_CLOCK_DELAY,
  16325. + VSC7385_CLOCK_DELAY,
  16326. + VSC7385_CLOCK_DELAY_MASK,
  16327. + VSC7385_CLOCK_DELAY);
  16328. + if (err)
  16329. + goto err;
  16330. +
  16331. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC,
  16332. + VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM,
  16333. + VSC7385_ADVPORTM_INIT,
  16334. + VSC7385_ADVPORTM_MASK,
  16335. + VSC7385_ADVPORTM_INIT);
  16336. + if (err)
  16337. + goto err;
  16338. +
  16339. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16340. + VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET);
  16341. + if (err)
  16342. + goto err;
  16343. +
  16344. + t = VSC73XX_MAC_CFG_INIT;
  16345. + t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg);
  16346. + t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel);
  16347. + if (pdata->mac_cfg.bit2)
  16348. + t |= VSC73XX_MAC_CFG_BIT2;
  16349. +
  16350. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16351. + VSC73XX_MAC_CFG, t);
  16352. + if (err)
  16353. + goto err;
  16354. +
  16355. + return 0;
  16356. +
  16357. + err:
  16358. + return err;
  16359. +}
  16360. +
  16361. +static int vsc7385_detect(struct vsc7385 *vsc)
  16362. +{
  16363. + struct spi_device *spi = vsc->spi;
  16364. + u32 t;
  16365. + u32 id;
  16366. + u32 rev;
  16367. + int err;
  16368. +
  16369. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16370. + VSC73XX_ICPU_MBOX_VAL, &t);
  16371. + if (err) {
  16372. + dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err);
  16373. + return err;
  16374. + }
  16375. +
  16376. + if (t == 0xffffffff) {
  16377. + dev_dbg(&spi->dev, "assert chip reset\n");
  16378. + if (vsc->pdata->reset)
  16379. + vsc->pdata->reset();
  16380. +
  16381. + }
  16382. +
  16383. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16384. + VSC73XX_ICPU_CHIPID, &t);
  16385. + if (err) {
  16386. + dev_err(&spi->dev, "unable to read chip id, err=%d\n", err);
  16387. + return err;
  16388. + }
  16389. +
  16390. + id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK;
  16391. + switch (id) {
  16392. + case VSC73XX_ICPU_CHIPID_ID_7385:
  16393. + case VSC73XX_ICPU_CHIPID_ID_7395:
  16394. + break;
  16395. + default:
  16396. + dev_err(&spi->dev, "unsupported chip, id=%04x\n", id);
  16397. + return -ENODEV;
  16398. + }
  16399. +
  16400. + rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) &
  16401. + VSC73XX_ICPU_CHIPID_REV_MASK;
  16402. + dev_info(&spi->dev, "VSC%04X (rev. %d) switch found \n", id, rev);
  16403. +
  16404. + return 0;
  16405. +}
  16406. +
  16407. +static int __devinit vsc7385_probe(struct spi_device *spi)
  16408. +{
  16409. + struct vsc7385 *vsc;
  16410. + struct vsc7385_platform_data *pdata;
  16411. + int err;
  16412. +
  16413. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
  16414. +
  16415. + pdata = spi->dev.platform_data;
  16416. + if (!pdata) {
  16417. + dev_err(&spi->dev, "no platform data specified\n");
  16418. + return-ENODEV;
  16419. + }
  16420. +
  16421. + vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
  16422. + if (!vsc) {
  16423. + dev_err(&spi->dev, "no memory for private data\n");
  16424. + return-ENOMEM;
  16425. + }
  16426. +
  16427. + mutex_init(&vsc->lock);
  16428. + vsc->pdata = pdata;
  16429. + vsc->spi = spi_dev_get(spi);
  16430. + dev_set_drvdata(&spi->dev, vsc);
  16431. +
  16432. + spi->mode = SPI_MODE_0;
  16433. + spi->bits_per_word = 8;
  16434. + err = spi_setup(spi);
  16435. + if (err) {
  16436. + dev_err(&spi->dev, "spi_setup failed, err=%d \n", err);
  16437. + goto err_drvdata;
  16438. + }
  16439. +
  16440. + err = vsc7385_detect(vsc);
  16441. + if (err) {
  16442. + dev_err(&spi->dev, "no chip found, err=%d \n", err);
  16443. + goto err_drvdata;
  16444. + }
  16445. +
  16446. + err = vsc7385_upload_ucode(vsc);
  16447. + if (err)
  16448. + goto err_drvdata;
  16449. +
  16450. + err = vsc7385_setup(vsc);
  16451. + if (err)
  16452. + goto err_drvdata;
  16453. +
  16454. + return 0;
  16455. +
  16456. + err_drvdata:
  16457. + dev_set_drvdata(&spi->dev, NULL);
  16458. + kfree(vsc);
  16459. + return err;
  16460. +}
  16461. +
  16462. +static int __devexit vsc7385_remove(struct spi_device *spi)
  16463. +{
  16464. + struct vsc7385_data *vsc;
  16465. +
  16466. + vsc = dev_get_drvdata(&spi->dev);
  16467. + dev_set_drvdata(&spi->dev, NULL);
  16468. + kfree(vsc);
  16469. +
  16470. + return 0;
  16471. +}
  16472. +
  16473. +static struct spi_driver vsc7385_driver = {
  16474. + .driver = {
  16475. + .name = DRV_NAME,
  16476. + .bus = &spi_bus_type,
  16477. + .owner = THIS_MODULE,
  16478. + },
  16479. + .probe = vsc7385_probe,
  16480. + .remove = __devexit_p(vsc7385_remove),
  16481. +};
  16482. +
  16483. +static int __init vsc7385_init(void)
  16484. +{
  16485. + return spi_register_driver(&vsc7385_driver);
  16486. +}
  16487. +module_init(vsc7385_init);
  16488. +
  16489. +static void __exit vsc7385_exit(void)
  16490. +{
  16491. + spi_unregister_driver(&vsc7385_driver);
  16492. +}
  16493. +module_exit(vsc7385_exit);
  16494. +
  16495. +MODULE_DESCRIPTION(DRV_DESC);
  16496. +MODULE_VERSION(DRV_VERSION);
  16497. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  16498. +MODULE_LICENSE("GPL v2");
  16499. +
  16500. diff -Nur linux-2.6.36.orig/drivers/usb/host/Kconfig linux-2.6.36/drivers/usb/host/Kconfig
  16501. --- linux-2.6.36.orig/drivers/usb/host/Kconfig 2010-10-20 22:30:22.000000000 +0200
  16502. +++ linux-2.6.36/drivers/usb/host/Kconfig 2010-12-17 18:34:51.000000000 +0100
  16503. @@ -112,6 +112,13 @@
  16504. support both high speed and full speed devices, or high speed
  16505. devices only.
  16506. +config USB_EHCI_AR71XX
  16507. + bool "USB EHCI support for AR71xx"
  16508. + depends on USB_EHCI_HCD && ATHEROS_AR71XX
  16509. + default y
  16510. + help
  16511. + Support for Atheros AR71xx built-in EHCI controller
  16512. +
  16513. config USB_EHCI_FSL
  16514. bool "Support for Freescale on-chip EHCI USB controller"
  16515. depends on USB_EHCI_HCD && FSL_SOC
  16516. @@ -225,6 +232,13 @@
  16517. Enables support for the on-chip OHCI controller on
  16518. OMAP3 and later chips.
  16519. +config USB_OHCI_AR71XX
  16520. + bool "USB OHCI support for Atheros AR71xx"
  16521. + depends on USB_OHCI_HCD && ATHEROS_AR71XX
  16522. + default y
  16523. + help
  16524. + Support for Atheros AR71xx built-in OHCI controller
  16525. +
  16526. config USB_OHCI_HCD_PPC_SOC
  16527. bool "OHCI support for on-chip PPC USB controller"
  16528. depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
  16529. diff -Nur linux-2.6.36.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.36/drivers/usb/host/ehci-ar71xx.c
  16530. --- linux-2.6.36.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16531. +++ linux-2.6.36/drivers/usb/host/ehci-ar71xx.c 2010-12-17 18:34:51.000000000 +0100
  16532. @@ -0,0 +1,242 @@
  16533. +/*
  16534. + * Bus Glue for Atheros AR71xx built-in EHCI controller.
  16535. + *
  16536. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  16537. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16538. + *
  16539. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16540. + * Copyright (C) 2007 Atheros Communications, Inc.
  16541. + *
  16542. + * This program is free software; you can redistribute it and/or modify it
  16543. + * under the terms of the GNU General Public License version 2 as published
  16544. + * by the Free Software Foundation.
  16545. + */
  16546. +
  16547. +#include <linux/platform_device.h>
  16548. +#include <linux/delay.h>
  16549. +
  16550. +#include <asm/mach-ar71xx/platform.h>
  16551. +
  16552. +extern int usb_disabled(void);
  16553. +
  16554. +static int ehci_ar71xx_init(struct usb_hcd *hcd)
  16555. +{
  16556. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16557. + int ret;
  16558. +
  16559. + ehci->caps = hcd->regs;
  16560. + ehci->regs = hcd->regs +
  16561. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16562. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16563. +
  16564. + ehci->sbrn = 0x20;
  16565. + ehci->has_synopsys_hc_bug = 1;
  16566. +
  16567. + ehci_reset(ehci);
  16568. +
  16569. + ret = ehci_init(hcd);
  16570. + if (ret)
  16571. + return ret;
  16572. +
  16573. + ehci_port_power(ehci, 0);
  16574. +
  16575. + return 0;
  16576. +}
  16577. +
  16578. +static int ehci_ar91xx_init(struct usb_hcd *hcd)
  16579. +{
  16580. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16581. + int ret;
  16582. +
  16583. + ehci->caps = hcd->regs + 0x100;
  16584. + ehci->regs = hcd->regs + 0x100 +
  16585. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16586. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16587. +
  16588. + hcd->has_tt = 1;
  16589. + ehci->sbrn = 0x20;
  16590. +
  16591. + ehci_reset(ehci);
  16592. +
  16593. + ret = ehci_init(hcd);
  16594. + if (ret)
  16595. + return ret;
  16596. +
  16597. + ehci_port_power(ehci, 0);
  16598. +
  16599. + return 0;
  16600. +}
  16601. +
  16602. +static int ehci_ar71xx_probe(const struct hc_driver *driver,
  16603. + struct usb_hcd **hcd_out,
  16604. + struct platform_device *pdev)
  16605. +{
  16606. + struct usb_hcd *hcd;
  16607. + struct resource *res;
  16608. + int irq;
  16609. + int ret;
  16610. +
  16611. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16612. + if (!res) {
  16613. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16614. + dev_name(&pdev->dev));
  16615. + return -ENODEV;
  16616. + }
  16617. + irq = res->start;
  16618. +
  16619. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16620. + if (!res) {
  16621. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16622. + dev_name(&pdev->dev));
  16623. + return -ENODEV;
  16624. + }
  16625. +
  16626. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16627. + if (!hcd)
  16628. + return -ENOMEM;
  16629. +
  16630. + hcd->rsrc_start = res->start;
  16631. + hcd->rsrc_len = res->end - res->start + 1;
  16632. +
  16633. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16634. + dev_dbg(&pdev->dev, "controller already in use\n");
  16635. + ret = -EBUSY;
  16636. + goto err_put_hcd;
  16637. + }
  16638. +
  16639. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16640. + if (!hcd->regs) {
  16641. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16642. + ret = -EFAULT;
  16643. + goto err_release_region;
  16644. + }
  16645. +
  16646. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  16647. + if (ret)
  16648. + goto err_iounmap;
  16649. +
  16650. + return 0;
  16651. +
  16652. + err_iounmap:
  16653. + iounmap(hcd->regs);
  16654. +
  16655. + err_release_region:
  16656. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16657. + err_put_hcd:
  16658. + usb_put_hcd(hcd);
  16659. + return ret;
  16660. +}
  16661. +
  16662. +static void ehci_ar71xx_remove(struct usb_hcd *hcd,
  16663. + struct platform_device *pdev)
  16664. +{
  16665. + usb_remove_hcd(hcd);
  16666. + iounmap(hcd->regs);
  16667. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16668. + usb_put_hcd(hcd);
  16669. +}
  16670. +
  16671. +static const struct hc_driver ehci_ar71xx_hc_driver = {
  16672. + .description = hcd_name,
  16673. + .product_desc = "Atheros AR71xx built-in EHCI controller",
  16674. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16675. +
  16676. + .irq = ehci_irq,
  16677. + .flags = HCD_MEMORY | HCD_USB2,
  16678. +
  16679. + .reset = ehci_ar71xx_init,
  16680. + .start = ehci_run,
  16681. + .stop = ehci_stop,
  16682. + .shutdown = ehci_shutdown,
  16683. +
  16684. + .urb_enqueue = ehci_urb_enqueue,
  16685. + .urb_dequeue = ehci_urb_dequeue,
  16686. + .endpoint_disable = ehci_endpoint_disable,
  16687. + .endpoint_reset = ehci_endpoint_reset,
  16688. +
  16689. + .get_frame_number = ehci_get_frame,
  16690. +
  16691. + .hub_status_data = ehci_hub_status_data,
  16692. + .hub_control = ehci_hub_control,
  16693. +#ifdef CONFIG_PM
  16694. + .hub_suspend = ehci_hub_suspend,
  16695. + .hub_resume = ehci_hub_resume,
  16696. +#endif
  16697. + .relinquish_port = ehci_relinquish_port,
  16698. + .port_handed_over = ehci_port_handed_over,
  16699. +
  16700. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16701. +};
  16702. +
  16703. +static const struct hc_driver ehci_ar91xx_hc_driver = {
  16704. + .description = hcd_name,
  16705. + .product_desc = "Atheros AR91xx built-in EHCI controller",
  16706. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16707. + .irq = ehci_irq,
  16708. + .flags = HCD_MEMORY | HCD_USB2,
  16709. +
  16710. + .reset = ehci_ar91xx_init,
  16711. + .start = ehci_run,
  16712. + .stop = ehci_stop,
  16713. + .shutdown = ehci_shutdown,
  16714. +
  16715. + .urb_enqueue = ehci_urb_enqueue,
  16716. + .urb_dequeue = ehci_urb_dequeue,
  16717. + .endpoint_disable = ehci_endpoint_disable,
  16718. + .endpoint_reset = ehci_endpoint_reset,
  16719. +
  16720. + .get_frame_number = ehci_get_frame,
  16721. +
  16722. + .hub_status_data = ehci_hub_status_data,
  16723. + .hub_control = ehci_hub_control,
  16724. +#ifdef CONFIG_PM
  16725. + .hub_suspend = ehci_hub_suspend,
  16726. + .hub_resume = ehci_hub_resume,
  16727. +#endif
  16728. + .relinquish_port = ehci_relinquish_port,
  16729. + .port_handed_over = ehci_port_handed_over,
  16730. +
  16731. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16732. +};
  16733. +
  16734. +static int ehci_ar71xx_driver_probe(struct platform_device *pdev)
  16735. +{
  16736. + struct ar71xx_ehci_platform_data *pdata;
  16737. + struct usb_hcd *hcd = NULL;
  16738. + int ret;
  16739. +
  16740. + if (usb_disabled())
  16741. + return -ENODEV;
  16742. +
  16743. + pdata = pdev->dev.platform_data;
  16744. + if (!pdata) {
  16745. + dev_err(&pdev->dev, "no platform data specified for %s\n",
  16746. + dev_name(&pdev->dev));
  16747. + return -ENODEV;
  16748. + }
  16749. +
  16750. + if (pdata->is_ar91xx)
  16751. + ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev);
  16752. + else
  16753. + ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev);
  16754. +
  16755. + return ret;
  16756. +}
  16757. +
  16758. +static int ehci_ar71xx_driver_remove(struct platform_device *pdev)
  16759. +{
  16760. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16761. +
  16762. + ehci_ar71xx_remove(hcd, pdev);
  16763. + return 0;
  16764. +}
  16765. +
  16766. +MODULE_ALIAS("platform:ar71xx-ehci");
  16767. +
  16768. +static struct platform_driver ehci_ar71xx_driver = {
  16769. + .probe = ehci_ar71xx_driver_probe,
  16770. + .remove = ehci_ar71xx_driver_remove,
  16771. + .driver = {
  16772. + .name = "ar71xx-ehci",
  16773. + }
  16774. +};
  16775. diff -Nur linux-2.6.36.orig/drivers/usb/host/ehci-hcd.c linux-2.6.36/drivers/usb/host/ehci-hcd.c
  16776. --- linux-2.6.36.orig/drivers/usb/host/ehci-hcd.c 2010-10-20 22:30:22.000000000 +0200
  16777. +++ linux-2.6.36/drivers/usb/host/ehci-hcd.c 2010-12-17 18:34:51.000000000 +0100
  16778. @@ -1197,6 +1197,11 @@
  16779. #define PLATFORM_DRIVER ehci_atmel_driver
  16780. #endif
  16781. +#ifdef CONFIG_USB_EHCI_AR71XX
  16782. +#include "ehci-ar71xx.c"
  16783. +#define PLATFORM_DRIVER ehci_ar71xx_driver
  16784. +#endif
  16785. +
  16786. #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
  16787. !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
  16788. !defined(XILINX_OF_PLATFORM_DRIVER)
  16789. diff -Nur linux-2.6.36.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.36/drivers/usb/host/ohci-ar71xx.c
  16790. --- linux-2.6.36.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16791. +++ linux-2.6.36/drivers/usb/host/ohci-ar71xx.c 2010-12-17 18:34:51.000000000 +0100
  16792. @@ -0,0 +1,165 @@
  16793. +/*
  16794. + * OHCI HCD (Host Controller Driver) for USB.
  16795. + *
  16796. + * Bus Glue for Atheros AR71xx built-in OHCI controller.
  16797. + *
  16798. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  16799. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16800. + *
  16801. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16802. + * Copyright (C) 2007 Atheros Communications, Inc.
  16803. + *
  16804. + * This program is free software; you can redistribute it and/or modify it
  16805. + * under the terms of the GNU General Public License version 2 as published
  16806. + * by the Free Software Foundation.
  16807. + */
  16808. +
  16809. +#include <linux/platform_device.h>
  16810. +#include <linux/delay.h>
  16811. +
  16812. +extern int usb_disabled(void);
  16813. +
  16814. +static int usb_hcd_ar71xx_probe(const struct hc_driver *driver,
  16815. + struct platform_device *pdev)
  16816. +{
  16817. + struct usb_hcd *hcd;
  16818. + struct resource *res;
  16819. + int irq;
  16820. + int ret;
  16821. +
  16822. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16823. + if (!res) {
  16824. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16825. + dev_name(&pdev->dev));
  16826. + return -ENODEV;
  16827. + }
  16828. + irq = res->start;
  16829. +
  16830. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16831. + if (!hcd)
  16832. + return -ENOMEM;
  16833. +
  16834. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16835. + if (!res) {
  16836. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16837. + dev_name(&pdev->dev));
  16838. + ret = -ENODEV;
  16839. + goto err_put_hcd;
  16840. + }
  16841. + hcd->rsrc_start = res->start;
  16842. + hcd->rsrc_len = res->end - res->start + 1;
  16843. +
  16844. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16845. + dev_dbg(&pdev->dev, "controller already in use\n");
  16846. + ret = -EBUSY;
  16847. + goto err_put_hcd;
  16848. + }
  16849. +
  16850. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16851. + if (!hcd->regs) {
  16852. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16853. + ret = -EFAULT;
  16854. + goto err_release_region;
  16855. + }
  16856. +
  16857. + ohci_hcd_init(hcd_to_ohci(hcd));
  16858. +
  16859. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  16860. + if (ret)
  16861. + goto err_stop_hcd;
  16862. +
  16863. + return 0;
  16864. +
  16865. + err_stop_hcd:
  16866. + iounmap(hcd->regs);
  16867. + err_release_region:
  16868. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16869. + err_put_hcd:
  16870. + usb_put_hcd(hcd);
  16871. + return ret;
  16872. +}
  16873. +
  16874. +void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  16875. +{
  16876. + usb_remove_hcd(hcd);
  16877. + iounmap(hcd->regs);
  16878. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16879. + usb_put_hcd(hcd);
  16880. +}
  16881. +
  16882. +static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd)
  16883. +{
  16884. + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  16885. + int ret;
  16886. +
  16887. + ret = ohci_init(ohci);
  16888. + if (ret < 0)
  16889. + return ret;
  16890. +
  16891. + ret = ohci_run(ohci);
  16892. + if (ret < 0)
  16893. + goto err;
  16894. +
  16895. + return 0;
  16896. +
  16897. + err:
  16898. + ohci_stop(hcd);
  16899. + return ret;
  16900. +}
  16901. +
  16902. +static const struct hc_driver ohci_ar71xx_hc_driver = {
  16903. + .description = hcd_name,
  16904. + .product_desc = "Atheros AR71xx built-in OHCI controller",
  16905. + .hcd_priv_size = sizeof(struct ohci_hcd),
  16906. +
  16907. + .irq = ohci_irq,
  16908. + .flags = HCD_USB11 | HCD_MEMORY,
  16909. +
  16910. + .start = ohci_ar71xx_start,
  16911. + .stop = ohci_stop,
  16912. + .shutdown = ohci_shutdown,
  16913. +
  16914. + .urb_enqueue = ohci_urb_enqueue,
  16915. + .urb_dequeue = ohci_urb_dequeue,
  16916. + .endpoint_disable = ohci_endpoint_disable,
  16917. +
  16918. + /*
  16919. + * scheduling support
  16920. + */
  16921. + .get_frame_number = ohci_get_frame,
  16922. +
  16923. + /*
  16924. + * root hub support
  16925. + */
  16926. + .hub_status_data = ohci_hub_status_data,
  16927. + .hub_control = ohci_hub_control,
  16928. + .start_port_reset = ohci_start_port_reset,
  16929. +};
  16930. +
  16931. +static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev)
  16932. +{
  16933. + if (usb_disabled())
  16934. + return -ENODEV;
  16935. +
  16936. + return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev);
  16937. +}
  16938. +
  16939. +static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev)
  16940. +{
  16941. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16942. +
  16943. + usb_hcd_ar71xx_remove(hcd, pdev);
  16944. + return 0;
  16945. +}
  16946. +
  16947. +MODULE_ALIAS("platform:ar71xx-ohci");
  16948. +
  16949. +static struct platform_driver ohci_hcd_ar71xx_driver = {
  16950. + .probe = ohci_hcd_ar71xx_drv_probe,
  16951. + .remove = ohci_hcd_ar71xx_drv_remove,
  16952. + .shutdown = usb_hcd_platform_shutdown,
  16953. + .driver = {
  16954. + .name = "ar71xx-ohci",
  16955. + .owner = THIS_MODULE,
  16956. + },
  16957. +};
  16958. diff -Nur linux-2.6.36.orig/drivers/usb/host/ohci-hcd.c linux-2.6.36/drivers/usb/host/ohci-hcd.c
  16959. --- linux-2.6.36.orig/drivers/usb/host/ohci-hcd.c 2010-10-20 22:30:22.000000000 +0200
  16960. +++ linux-2.6.36/drivers/usb/host/ohci-hcd.c 2010-12-17 18:34:51.000000000 +0100
  16961. @@ -1100,6 +1100,11 @@
  16962. #define PLATFORM_DRIVER ohci_hcd_jz4740_driver
  16963. #endif
  16964. +#ifdef CONFIG_USB_OHCI_AR71XX
  16965. +#include "ohci-ar71xx.c"
  16966. +#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
  16967. +#endif
  16968. +
  16969. #if !defined(PCI_DRIVER) && \
  16970. !defined(PLATFORM_DRIVER) && \
  16971. !defined(OMAP1_PLATFORM_DRIVER) && \
  16972. diff -Nur linux-2.6.36.orig/drivers/watchdog/Kconfig linux-2.6.36/drivers/watchdog/Kconfig
  16973. --- linux-2.6.36.orig/drivers/watchdog/Kconfig 2010-10-20 22:30:22.000000000 +0200
  16974. +++ linux-2.6.36/drivers/watchdog/Kconfig 2010-12-17 18:34:51.000000000 +0100
  16975. @@ -916,6 +916,13 @@
  16976. from the first interrupt, it is then only poked when the
  16977. device is written.
  16978. +config AR71XX_WDT
  16979. + tristate "Atheros AR71xx Watchdog Timer"
  16980. + depends on ATHEROS_AR71XX
  16981. + help
  16982. + Hardware driver for the built-in watchdog timer on the Atheros
  16983. + AR71xx SoCs.
  16984. +
  16985. # PARISC Architecture
  16986. # POWERPC Architecture
  16987. diff -Nur linux-2.6.36.orig/drivers/watchdog/Makefile linux-2.6.36/drivers/watchdog/Makefile
  16988. --- linux-2.6.36.orig/drivers/watchdog/Makefile 2010-10-20 22:30:22.000000000 +0200
  16989. +++ linux-2.6.36/drivers/watchdog/Makefile 2010-12-17 18:34:51.000000000 +0100
  16990. @@ -116,6 +116,7 @@
  16991. obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
  16992. obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
  16993. obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
  16994. +obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
  16995. obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
  16996. octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
  16997. diff -Nur linux-2.6.36.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.36/drivers/watchdog/ar71xx_wdt.c
  16998. --- linux-2.6.36.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100
  16999. +++ linux-2.6.36/drivers/watchdog/ar71xx_wdt.c 2010-12-17 18:34:51.000000000 +0100
  17000. @@ -0,0 +1,270 @@
  17001. +/*
  17002. + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer.
  17003. + *
  17004. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  17005. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  17006. + *
  17007. + * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
  17008. + * Author: Deepak Saxena <dsaxena@plexity.net>
  17009. + * Copyright 2004 (c) MontaVista, Software, Inc.
  17010. + *
  17011. + * which again was based on sa1100 driver,
  17012. + * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
  17013. + *
  17014. + * This program is free software; you can redistribute it and/or modify it
  17015. + * under the terms of the GNU General Public License version 2 as published
  17016. + * by the Free Software Foundation.
  17017. + *
  17018. + */
  17019. +
  17020. +#include <linux/bitops.h>
  17021. +#include <linux/errno.h>
  17022. +#include <linux/fs.h>
  17023. +#include <linux/init.h>
  17024. +#include <linux/kernel.h>
  17025. +#include <linux/miscdevice.h>
  17026. +#include <linux/module.h>
  17027. +#include <linux/moduleparam.h>
  17028. +#include <linux/platform_device.h>
  17029. +#include <linux/types.h>
  17030. +#include <linux/watchdog.h>
  17031. +
  17032. +#include <asm/mach-ar71xx/ar71xx.h>
  17033. +
  17034. +#define DRV_NAME "ar71xx-wdt"
  17035. +#define DRV_DESC "Atheros AR71xx hardware watchdog driver"
  17036. +#define DRV_VERSION "0.1.0"
  17037. +
  17038. +#define WDT_TIMEOUT 15 /* seconds */
  17039. +
  17040. +static int nowayout = WATCHDOG_NOWAYOUT;
  17041. +
  17042. +#ifdef CONFIG_WATCHDOG_NOWAYOUT
  17043. +module_param(nowayout, int, 0);
  17044. +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  17045. + "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  17046. +#endif
  17047. +
  17048. +static unsigned long wdt_flags;
  17049. +
  17050. +#define WDT_FLAGS_BUSY 0
  17051. +#define WDT_FLAGS_EXPECT_CLOSE 1
  17052. +
  17053. +static int wdt_timeout = WDT_TIMEOUT;
  17054. +static int boot_status;
  17055. +static int max_timeout;
  17056. +
  17057. +static void inline ar71xx_wdt_keepalive(void)
  17058. +{
  17059. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout);
  17060. +}
  17061. +
  17062. +static void inline ar71xx_wdt_enable(void)
  17063. +{
  17064. + printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n");
  17065. + ar71xx_wdt_keepalive();
  17066. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
  17067. +}
  17068. +
  17069. +static void inline ar71xx_wdt_disable(void)
  17070. +{
  17071. + printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n");
  17072. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
  17073. +}
  17074. +
  17075. +static int ar71xx_wdt_set_timeout(int val)
  17076. +{
  17077. + if (val < 1 || val > max_timeout)
  17078. + return -EINVAL;
  17079. +
  17080. + wdt_timeout = val;
  17081. + ar71xx_wdt_keepalive();
  17082. +
  17083. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout);
  17084. +
  17085. + return 0;
  17086. +}
  17087. +
  17088. +static int ar71xx_wdt_open(struct inode *inode, struct file *file)
  17089. +{
  17090. + if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
  17091. + return -EBUSY;
  17092. +
  17093. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17094. +
  17095. + ar71xx_wdt_enable();
  17096. +
  17097. + return nonseekable_open(inode, file);
  17098. +}
  17099. +
  17100. +static int ar71xx_wdt_release(struct inode *inode, struct file *file)
  17101. +{
  17102. + if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) {
  17103. + ar71xx_wdt_disable();
  17104. + } else {
  17105. + printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, "
  17106. + "watchdog timer will not stop!\n");
  17107. + }
  17108. +
  17109. + clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
  17110. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17111. +
  17112. + return 0;
  17113. +}
  17114. +
  17115. +static ssize_t ar71xx_wdt_write(struct file *file, const char *data,
  17116. + size_t len, loff_t *ppos)
  17117. +{
  17118. + if (len) {
  17119. + if (!nowayout) {
  17120. + size_t i;
  17121. +
  17122. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17123. +
  17124. + for (i = 0; i != len; i++) {
  17125. + char c;
  17126. +
  17127. + if (get_user(c, data + i))
  17128. + return -EFAULT;
  17129. +
  17130. + if (c == 'V')
  17131. + set_bit(WDT_FLAGS_EXPECT_CLOSE,
  17132. + &wdt_flags);
  17133. + }
  17134. + }
  17135. +
  17136. + ar71xx_wdt_keepalive();
  17137. + }
  17138. +
  17139. + return len;
  17140. +}
  17141. +
  17142. +static struct watchdog_info ar71xx_wdt_info = {
  17143. + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
  17144. + WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
  17145. + .firmware_version = 0,
  17146. + .identity = "AR71XX watchdog",
  17147. +};
  17148. +
  17149. +static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file,
  17150. + unsigned int cmd, unsigned long arg)
  17151. +{
  17152. + int t;
  17153. + int ret;
  17154. +
  17155. + switch (cmd) {
  17156. + case WDIOC_GETSUPPORT:
  17157. + ret = copy_to_user((struct watchdog_info *)arg,
  17158. + &ar71xx_wdt_info,
  17159. + sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0;
  17160. + break;
  17161. +
  17162. + case WDIOC_GETSTATUS:
  17163. + ret = put_user(0, (int *)arg) ? -EFAULT : 0;
  17164. + break;
  17165. +
  17166. + case WDIOC_GETBOOTSTATUS:
  17167. + ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0;
  17168. + break;
  17169. +
  17170. + case WDIOC_KEEPALIVE:
  17171. + ar71xx_wdt_keepalive();
  17172. + ret = 0;
  17173. + break;
  17174. +
  17175. + case WDIOC_SETTIMEOUT:
  17176. + ret = get_user(t, (int *)arg) ? -EFAULT : 0;
  17177. + if (ret)
  17178. + break;
  17179. +
  17180. + ret = ar71xx_wdt_set_timeout(t);
  17181. + if (ret)
  17182. + break;
  17183. +
  17184. + /* fallthrough */
  17185. + case WDIOC_GETTIMEOUT:
  17186. + ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0;
  17187. + break;
  17188. +
  17189. + default:
  17190. + ret = -ENOTTY;
  17191. + break;
  17192. + }
  17193. +
  17194. + return ret;
  17195. +}
  17196. +
  17197. +static const struct file_operations ar71xx_wdt_fops = {
  17198. + .owner = THIS_MODULE,
  17199. + .write = ar71xx_wdt_write,
  17200. + .ioctl = ar71xx_wdt_ioctl,
  17201. + .open = ar71xx_wdt_open,
  17202. + .release = ar71xx_wdt_release,
  17203. +};
  17204. +
  17205. +static struct miscdevice ar71xx_wdt_miscdev = {
  17206. + .minor = WATCHDOG_MINOR,
  17207. + .name = "watchdog",
  17208. + .fops = &ar71xx_wdt_fops,
  17209. +};
  17210. +
  17211. +static int __devinit ar71xx_wdt_probe(struct platform_device *pdev)
  17212. +{
  17213. + int ret;
  17214. +
  17215. + max_timeout = (0xfffffffful / ar71xx_ahb_freq);
  17216. + wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
  17217. +
  17218. + boot_status =
  17219. + (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ?
  17220. + WDIOF_CARDRESET : 0;
  17221. +
  17222. + ret = misc_register(&ar71xx_wdt_miscdev);
  17223. + if (ret)
  17224. + goto err_out;
  17225. +
  17226. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  17227. +
  17228. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n",
  17229. + wdt_timeout, max_timeout);
  17230. +
  17231. + return 0;
  17232. +
  17233. +err_out:
  17234. + return ret;
  17235. +}
  17236. +
  17237. +static int __devexit ar71xx_wdt_remove(struct platform_device *pdev)
  17238. +{
  17239. + misc_deregister(&ar71xx_wdt_miscdev);
  17240. + return 0;
  17241. +}
  17242. +
  17243. +static struct platform_driver ar71xx_wdt_driver = {
  17244. + .probe = ar71xx_wdt_probe,
  17245. + .remove = __devexit_p(ar71xx_wdt_remove),
  17246. + .driver = {
  17247. + .name = DRV_NAME,
  17248. + .owner = THIS_MODULE,
  17249. + },
  17250. +};
  17251. +
  17252. +static int __init ar71xx_wdt_init(void)
  17253. +{
  17254. + return platform_driver_register(&ar71xx_wdt_driver);
  17255. +}
  17256. +module_init(ar71xx_wdt_init);
  17257. +
  17258. +static void __exit ar71xx_wdt_exit(void)
  17259. +{
  17260. + platform_driver_unregister(&ar71xx_wdt_driver);
  17261. +}
  17262. +module_exit(ar71xx_wdt_exit);
  17263. +
  17264. +MODULE_DESCRIPTION(DRV_DESC);
  17265. +MODULE_VERSION(DRV_VERSION);
  17266. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
  17267. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
  17268. +MODULE_LICENSE("GPL v2");
  17269. +MODULE_ALIAS("platform:" DRV_NAME);
  17270. +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  17271. diff -Nur linux-2.6.36.orig/include/linux/ath9k_platform.h linux-2.6.36/include/linux/ath9k_platform.h
  17272. --- linux-2.6.36.orig/include/linux/ath9k_platform.h 2010-10-20 22:30:22.000000000 +0200
  17273. +++ linux-2.6.36/include/linux/ath9k_platform.h 2010-12-17 18:34:51.000000000 +0100
  17274. @@ -1,19 +1,11 @@
  17275. /*
  17276. - * Copyright (c) 2008 Atheros Communications Inc.
  17277. - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  17278. - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
  17279. + * ath9k platform data defines
  17280. *
  17281. - * Permission to use, copy, modify, and/or distribute this software for any
  17282. - * purpose with or without fee is hereby granted, provided that the above
  17283. - * copyright notice and this permission notice appear in all copies.
  17284. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  17285. *
  17286. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  17287. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  17288. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  17289. - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17290. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17291. - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17292. - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17293. + * This program is free software; you can redistribute it and/or modify it
  17294. + * under the terms of the GNU General Public License version 2 as published
  17295. + * by the Free Software Foundation.
  17296. */
  17297. #ifndef _LINUX_ATH9K_PLATFORM_H
  17298. @@ -23,6 +15,9 @@
  17299. struct ath9k_platform_data {
  17300. u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  17301. + u8 *macaddr;
  17302. +
  17303. + unsigned long quirk_wndr3700:1;
  17304. };
  17305. #endif /* _LINUX_ATH9K_PLATFORM_H */
  17306. diff -Nur linux-2.6.36.orig/include/linux/gpio_buttons.h linux-2.6.36/include/linux/gpio_buttons.h
  17307. --- linux-2.6.36.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100
  17308. +++ linux-2.6.36/include/linux/gpio_buttons.h 2010-12-17 18:34:51.000000000 +0100
  17309. @@ -0,0 +1,33 @@
  17310. +/*
  17311. + * Definitions for the GPIO buttons interface driver
  17312. + *
  17313. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  17314. + *
  17315. + * This file was based on: /include/linux/gpio_keys.h
  17316. + * The original gpio_keys.h seems not to have a license.
  17317. + *
  17318. + * This program is free software; you can redistribute it and/or modify
  17319. + * it under the terms of the GNU General Public License version 2 as
  17320. + * published by the Free Software Foundation.
  17321. + *
  17322. + */
  17323. +
  17324. +#ifndef _GPIO_BUTTONS_H_
  17325. +#define _GPIO_BUTTONS_H_
  17326. +
  17327. +struct gpio_button {
  17328. + int gpio; /* GPIO line number */
  17329. + int active_low;
  17330. + char *desc; /* button description */
  17331. + int type; /* input event type (EV_KEY, EV_SW) */
  17332. + int code; /* input event code (KEY_*, SW_*) */
  17333. + int threshold; /* count threshold */
  17334. +};
  17335. +
  17336. +struct gpio_buttons_platform_data {
  17337. + struct gpio_button *buttons;
  17338. + int nbuttons; /* number of buttons */
  17339. + int poll_interval; /* polling interval */
  17340. +};
  17341. +
  17342. +#endif /* _GPIO_BUTTONS_H_ */
  17343. diff -Nur linux-2.6.36.orig/include/linux/gpio_dev.h linux-2.6.36/include/linux/gpio_dev.h
  17344. --- linux-2.6.36.orig/include/linux/gpio_dev.h 1970-01-01 01:00:00.000000000 +0100
  17345. +++ linux-2.6.36/include/linux/gpio_dev.h 2010-12-17 18:34:51.000000000 +0100
  17346. @@ -0,0 +1,11 @@
  17347. +#ifndef _GPIODEV_H__
  17348. +#define _GPIODEV_H__
  17349. +
  17350. +#define IOC_GPIODEV_MAGIC 'B'
  17351. +#define GPIO_GET _IO(IOC_GPIODEV_MAGIC, 10)
  17352. +#define GPIO_SET _IO(IOC_GPIODEV_MAGIC, 11)
  17353. +#define GPIO_CLEAR _IO(IOC_GPIODEV_MAGIC, 12)
  17354. +#define GPIO_DIR_IN _IO(IOC_GPIODEV_MAGIC, 13)
  17355. +#define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 14)
  17356. +
  17357. +#endif
  17358. diff -Nur linux-2.6.36.orig/include/linux/netdevice.h linux-2.6.36/include/linux/netdevice.h
  17359. --- linux-2.6.36.orig/include/linux/netdevice.h 2010-10-20 22:30:22.000000000 +0200
  17360. +++ linux-2.6.36/include/linux/netdevice.h 2010-12-17 18:34:51.000000000 +0100
  17361. @@ -949,6 +949,7 @@
  17362. void *ax25_ptr; /* AX.25 specific data */
  17363. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  17364. assign before registering */
  17365. + void *phy_ptr; /* PHY device specific data */
  17366. /*
  17367. * Cache line mostly used on receive path (including eth_type_trans())
  17368. diff -Nur linux-2.6.36.orig/include/linux/nxp_74hc153.h linux-2.6.36/include/linux/nxp_74hc153.h
  17369. --- linux-2.6.36.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100
  17370. +++ linux-2.6.36/include/linux/nxp_74hc153.h 2010-12-17 18:34:51.000000000 +0100
  17371. @@ -0,0 +1,24 @@
  17372. +/*
  17373. + * NXP 74HC153 - Dual 4-input multiplexer defines
  17374. + *
  17375. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  17376. + *
  17377. + * This program is free software; you can redistribute it and/or modify
  17378. + * it under the terms of the GNU General Public License version 2 as
  17379. + * published by the Free Software Foundation.
  17380. + */
  17381. +
  17382. +#ifndef _NXP_74HC153_H
  17383. +#define _NXP_74HC153_H
  17384. +
  17385. +#define NXP_74HC153_DRIVER_NAME "nxp-74hc153"
  17386. +
  17387. +struct nxp_74hc153_platform_data {
  17388. + unsigned gpio_base;
  17389. + unsigned gpio_pin_s0;
  17390. + unsigned gpio_pin_s1;
  17391. + unsigned gpio_pin_1y;
  17392. + unsigned gpio_pin_2y;
  17393. +};
  17394. +
  17395. +#endif /* _NXP_74HC153_H */
  17396. diff -Nur linux-2.6.36.orig/include/linux/phy.h linux-2.6.36/include/linux/phy.h
  17397. --- linux-2.6.36.orig/include/linux/phy.h 2010-10-20 22:30:22.000000000 +0200
  17398. +++ linux-2.6.36/include/linux/phy.h 2010-12-17 18:34:51.000000000 +0100
  17399. @@ -332,6 +332,20 @@
  17400. void (*adjust_link)(struct net_device *dev);
  17401. void (*adjust_state)(struct net_device *dev);
  17402. +
  17403. + /*
  17404. + * By default these point to the original functions
  17405. + * with the same name. adding them to the phy_device
  17406. + * allows the phy driver to override them for packet
  17407. + * mangling if the ethernet driver supports it
  17408. + * This is required to support some really horrible
  17409. + * switches such as the Marvell 88E6060
  17410. + */
  17411. + int (*netif_receive_skb)(struct sk_buff *skb);
  17412. + int (*netif_rx)(struct sk_buff *skb);
  17413. +
  17414. + /* alignment offset for packets */
  17415. + int pkt_align;
  17416. };
  17417. #define to_phy_device(d) container_of(d, struct phy_device, dev)
  17418. @@ -519,6 +533,7 @@
  17419. void phy_stop_machine(struct phy_device *phydev);
  17420. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17421. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17422. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  17423. int phy_mii_ioctl(struct phy_device *phydev,
  17424. struct ifreq *ifr, int cmd);
  17425. int phy_start_interrupts(struct phy_device *phydev);
  17426. diff -Nur linux-2.6.36.orig/include/linux/spi/vsc7385.h linux-2.6.36/include/linux/spi/vsc7385.h
  17427. --- linux-2.6.36.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100
  17428. +++ linux-2.6.36/include/linux/spi/vsc7385.h 2010-12-17 18:34:51.000000000 +0100
  17429. @@ -0,0 +1,19 @@
  17430. +/*
  17431. + * Platform data definition for the Vitesse VSC7385 ethernet switch driver
  17432. + *
  17433. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  17434. + *
  17435. + * This program is free software; you can redistribute it and/or modify it
  17436. + * under the terms of the GNU General Public License version 2 as published
  17437. + * by the Free Software Foundation.
  17438. + */
  17439. +
  17440. +struct vsc7385_platform_data {
  17441. + void (* reset)(void);
  17442. + char *ucode_name;
  17443. + struct {
  17444. + u32 tx_ipg:5;
  17445. + u32 bit2:1;
  17446. + u32 clk_sel:3;
  17447. + } mac_cfg;
  17448. +};
  17449. diff -Nur linux-2.6.36.orig/net/dsa/ar7240.c linux-2.6.36/net/dsa/ar7240.c
  17450. --- linux-2.6.36.orig/net/dsa/ar7240.c 1970-01-01 01:00:00.000000000 +0100
  17451. +++ linux-2.6.36/net/dsa/ar7240.c 2010-12-17 18:34:51.000000000 +0100
  17452. @@ -0,0 +1,736 @@
  17453. +/*
  17454. + * DSA driver for the built-in ethernet switch of the Atheros AR7240 SoC
  17455. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  17456. + *
  17457. + * This file was based on:
  17458. + * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
  17459. + * Copyright (c) 2008 Marvell Semiconductor
  17460. + *
  17461. + * This program is free software; you can redistribute it and/or modify it
  17462. + * under the terms of the GNU General Public License version 2 as published
  17463. + * by the Free Software Foundation.
  17464. + *
  17465. + */
  17466. +
  17467. +#include <linux/etherdevice.h>
  17468. +#include <linux/list.h>
  17469. +#include <linux/netdevice.h>
  17470. +#include <linux/phy.h>
  17471. +#include <linux/mii.h>
  17472. +#include <linux/bitops.h>
  17473. +
  17474. +#include "dsa_priv.h"
  17475. +
  17476. +#define BITM(_count) (BIT(_count) - 1)
  17477. +
  17478. +#define AR7240_REG_MASK_CTRL 0x00
  17479. +#define AR7240_MASK_CTRL_REVISION_M BITM(8)
  17480. +#define AR7240_MASK_CTRL_VERSION_M BITM(8)
  17481. +#define AR7240_MASK_CTRL_VERSION_S 8
  17482. +#define AR7240_MASK_CTRL_SOFT_RESET BIT(31)
  17483. +
  17484. +#define AR7240_REG_MAC_ADDR0 0x20
  17485. +#define AR7240_REG_MAC_ADDR1 0x24
  17486. +
  17487. +#define AR7240_REG_FLOOD_MASK 0x2c
  17488. +#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26)
  17489. +
  17490. +#define AR7240_REG_GLOBAL_CTRL 0x30
  17491. +#define AR7240_GLOBAL_CTRL_MTU_M BITM(12)
  17492. +
  17493. +#define AR7240_REG_AT_CTRL 0x5c
  17494. +#define AR7240_AT_CTRL_ARP_EN BIT(20)
  17495. +
  17496. +#define AR7240_REG_TAG_PRIORITY 0x70
  17497. +
  17498. +#define AR7240_REG_SERVICE_TAG 0x74
  17499. +#define AR7240_SERVICE_TAG_M BITM(16)
  17500. +
  17501. +#define AR7240_REG_CPU_PORT 0x78
  17502. +#define AR7240_MIRROR_PORT_S 4
  17503. +#define AR7240_CPU_PORT_EN BIT(8)
  17504. +
  17505. +#define AR7240_REG_MIB_FUNCTION0 0x80
  17506. +#define AR7240_MIB_TIMER_M BITM(16)
  17507. +#define AR7240_MIB_AT_HALF_EN BIT(16)
  17508. +#define AR7240_MIB_BUSY BIT(17)
  17509. +#define AR7240_MIB_FUNC_S 24
  17510. +#define AR7240_MIB_FUNC_NO_OP 0x0
  17511. +#define AR7240_MIB_FUNC_FLUSH 0x1
  17512. +#define AR7240_MIB_FUNC_CAPTURE 0x3
  17513. +
  17514. +#define AR7240_REG_MDIO_CTRL 0x98
  17515. +#define AR7240_MDIO_CTRL_DATA_M BITM(16)
  17516. +#define AR7240_MDIO_CTRL_REG_ADDR_S 16
  17517. +#define AR7240_MDIO_CTRL_PHY_ADDR_S 21
  17518. +#define AR7240_MDIO_CTRL_CMD_WRITE 0
  17519. +#define AR7240_MDIO_CTRL_CMD_READ BIT(27)
  17520. +#define AR7240_MDIO_CTRL_MASTER_EN BIT(30)
  17521. +#define AR7240_MDIO_CTRL_BUSY BIT(31)
  17522. +
  17523. +#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100)
  17524. +
  17525. +#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00)
  17526. +#define AR7240_PORT_STATUS_SPEED_M BITM(2)
  17527. +#define AR7240_PORT_STATUS_SPEED_10 0
  17528. +#define AR7240_PORT_STATUS_SPEED_100 1
  17529. +#define AR7240_PORT_STATUS_SPEED_1000 2
  17530. +#define AR7240_PORT_STATUS_TXMAC BIT(2)
  17531. +#define AR7240_PORT_STATUS_RXMAC BIT(3)
  17532. +#define AR7240_PORT_STATUS_TXFLOW BIT(4)
  17533. +#define AR7240_PORT_STATUS_RXFLOW BIT(5)
  17534. +#define AR7240_PORT_STATUS_DUPLEX BIT(6)
  17535. +#define AR7240_PORT_STATUS_LINK_UP BIT(8)
  17536. +#define AR7240_PORT_STATUS_LINK_AUTO BIT(9)
  17537. +#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10)
  17538. +
  17539. +#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04)
  17540. +#define AR7240_PORT_CTRL_STATE_M BITM(3)
  17541. +#define AR7240_PORT_CTRL_STATE_DISABLED 0
  17542. +#define AR7240_PORT_CTRL_STATE_BLOCK 1
  17543. +#define AR7240_PORT_CTRL_STATE_LISTEN 2
  17544. +#define AR7240_PORT_CTRL_STATE_LEARN 3
  17545. +#define AR7240_PORT_CTRL_STATE_FORWARD 4
  17546. +#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7)
  17547. +#define AR7240_PORT_CTRL_VLAN_MODE_S 8
  17548. +#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0
  17549. +#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1
  17550. +#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2
  17551. +#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3
  17552. +#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10)
  17553. +#define AR7240_PORT_CTRL_HEADER BIT(11)
  17554. +#define AR7240_PORT_CTRL_MAC_LOOP BIT(12)
  17555. +#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13)
  17556. +#define AR7240_PORT_CTRL_LEARN BIT(14)
  17557. +#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15)
  17558. +#define AR7240_PORT_CTRL_MIRROR_TX BIT(16)
  17559. +#define AR7240_PORT_CTRL_MIRROR_RX BIT(17)
  17560. +
  17561. +#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08)
  17562. +
  17563. +#define AR7240_PORT_VLAN_DEFAULT_ID_S 0
  17564. +#define AR7240_PORT_VLAN_DEST_PORTS_S 16
  17565. +
  17566. +#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100)
  17567. +
  17568. +#define AR7240_STATS_RXBROAD 0x00
  17569. +#define AR7240_STATS_RXPAUSE 0x04
  17570. +#define AR7240_STATS_RXMULTI 0x08
  17571. +#define AR7240_STATS_RXFCSERR 0x0c
  17572. +#define AR7240_STATS_RXALIGNERR 0x10
  17573. +#define AR7240_STATS_RXRUNT 0x14
  17574. +#define AR7240_STATS_RXFRAGMENT 0x18
  17575. +#define AR7240_STATS_RX64BYTE 0x1c
  17576. +#define AR7240_STATS_RX128BYTE 0x20
  17577. +#define AR7240_STATS_RX256BYTE 0x24
  17578. +#define AR7240_STATS_RX512BYTE 0x28
  17579. +#define AR7240_STATS_RX1024BYTE 0x2c
  17580. +#define AR7240_STATS_RX1518BYTE 0x30
  17581. +#define AR7240_STATS_RXMAXBYTE 0x34
  17582. +#define AR7240_STATS_RXTOOLONG 0x38
  17583. +#define AR7240_STATS_RXGOODBYTE 0x3c
  17584. +#define AR7240_STATS_RXBADBYTE 0x44
  17585. +#define AR7240_STATS_RXOVERFLOW 0x4c
  17586. +#define AR7240_STATS_FILTERED 0x50
  17587. +#define AR7240_STATS_TXBROAD 0x54
  17588. +#define AR7240_STATS_TXPAUSE 0x58
  17589. +#define AR7240_STATS_TXMULTI 0x5c
  17590. +#define AR7240_STATS_TXUNDERRUN 0x60
  17591. +#define AR7240_STATS_TX64BYTE 0x64
  17592. +#define AR7240_STATS_TX128BYTE 0x68
  17593. +#define AR7240_STATS_TX256BYTE 0x6c
  17594. +#define AR7240_STATS_TX512BYTE 0x70
  17595. +#define AR7240_STATS_TX1024BYTE 0x74
  17596. +#define AR7240_STATS_TX1518BYTE 0x78
  17597. +#define AR7240_STATS_TXMAXBYTE 0x7c
  17598. +#define AR7240_STATS_TXOVERSIZE 0x80
  17599. +#define AR7240_STATS_TXBYTE 0x84
  17600. +#define AR7240_STATS_TXCOLLISION 0x8c
  17601. +#define AR7240_STATS_TXABORTCOL 0x90
  17602. +#define AR7240_STATS_TXMULTICOL 0x94
  17603. +#define AR7240_STATS_TXSINGLECOL 0x98
  17604. +#define AR7240_STATS_TXEXCDEFER 0x9c
  17605. +#define AR7240_STATS_TXDEFER 0xa0
  17606. +#define AR7240_STATS_TXLATECOL 0xa4
  17607. +
  17608. +#define AR7240_PORT_CPU 0
  17609. +#define AR7240_NUM_PORTS 6
  17610. +#define AR7240_NUM_PHYS 5
  17611. +
  17612. +#define AR7240_PHY_ID1 0x004d
  17613. +#define AR7240_PHY_ID2 0xd041
  17614. +
  17615. +#define AR7240_PORT_MASK(_port) BIT((_port))
  17616. +#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS)
  17617. +#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port)))
  17618. +
  17619. +struct ar7240sw {
  17620. + struct mii_bus *mii_bus;
  17621. + struct mutex reg_mutex;
  17622. + struct mutex stats_mutex;
  17623. +};
  17624. +
  17625. +struct ar7240sw_hw_stat {
  17626. + char string[ETH_GSTRING_LEN];
  17627. + int sizeof_stat;
  17628. + int reg;
  17629. +};
  17630. +
  17631. +static inline struct ar7240sw *dsa_to_ar7240sw(struct dsa_switch *ds)
  17632. +{
  17633. + return (struct ar7240sw *)(ds + 1);
  17634. +}
  17635. +
  17636. +static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
  17637. +{
  17638. + as->mii_bus = mii;
  17639. + mutex_init(&as->reg_mutex);
  17640. + mutex_init(&as->stats_mutex);
  17641. +}
  17642. +
  17643. +static inline u16 mk_phy_addr(u32 reg)
  17644. +{
  17645. + return (0x17 & ((reg >> 4) | 0x10));
  17646. +}
  17647. +
  17648. +static inline u16 mk_phy_reg(u32 reg)
  17649. +{
  17650. + return ((reg << 1) & 0x1e);
  17651. +}
  17652. +
  17653. +static inline u16 mk_high_addr(u32 reg)
  17654. +{
  17655. + return ((reg >> 7) & 0x1ff);
  17656. +}
  17657. +
  17658. +static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg)
  17659. +{
  17660. + struct mii_bus *mii = as->mii_bus;
  17661. + u16 phy_addr;
  17662. + u16 phy_reg;
  17663. + u32 hi, lo;
  17664. +
  17665. + reg = (reg & 0xfffffffc) >> 2;
  17666. +
  17667. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17668. +
  17669. + phy_addr = mk_phy_addr(reg);
  17670. + phy_reg = mk_phy_reg(reg);
  17671. +
  17672. + lo = (u32) mdiobus_read(mii, phy_addr, phy_reg);
  17673. + hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1);
  17674. +
  17675. + return ((hi << 16) | lo);
  17676. +}
  17677. +
  17678. +static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val)
  17679. +{
  17680. + struct mii_bus *mii = as->mii_bus;
  17681. + u16 phy_addr;
  17682. + u16 phy_reg;
  17683. +
  17684. + reg = (reg & 0xfffffffc) >> 2;
  17685. +
  17686. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17687. +
  17688. + phy_addr = mk_phy_addr(reg);
  17689. + phy_reg = mk_phy_reg(reg);
  17690. +
  17691. + mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16));
  17692. + mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff));
  17693. +}
  17694. +
  17695. +static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr)
  17696. +{
  17697. + u32 ret;
  17698. +
  17699. + mutex_lock(&as->reg_mutex);
  17700. + ret = __ar7240sw_reg_read(as, reg_addr);
  17701. + mutex_unlock(&as->reg_mutex);
  17702. +
  17703. + return ret;
  17704. +}
  17705. +
  17706. +static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val)
  17707. +{
  17708. + mutex_lock(&as->reg_mutex);
  17709. + __ar7240sw_reg_write(as, reg_addr, reg_val);
  17710. + mutex_unlock(&as->reg_mutex);
  17711. +}
  17712. +
  17713. +static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val)
  17714. +{
  17715. + u32 t;
  17716. +
  17717. + mutex_lock(&as->reg_mutex);
  17718. + t = __ar7240sw_reg_read(as, reg);
  17719. + t &= ~mask;
  17720. + t |= val;
  17721. + __ar7240sw_reg_write(as, reg, t);
  17722. + mutex_unlock(&as->reg_mutex);
  17723. +
  17724. + return t;
  17725. +}
  17726. +
  17727. +static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val)
  17728. +{
  17729. + u32 t;
  17730. +
  17731. + mutex_lock(&as->reg_mutex);
  17732. + t = __ar7240sw_reg_read(as, reg);
  17733. + t |= val;
  17734. + __ar7240sw_reg_write(as, reg, t);
  17735. + mutex_unlock(&as->reg_mutex);
  17736. +}
  17737. +
  17738. +static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
  17739. + unsigned timeout)
  17740. +{
  17741. + int i;
  17742. +
  17743. + for (i = 0; i < timeout; i++) {
  17744. + u32 t;
  17745. +
  17746. + t = ar7240sw_reg_read(as, reg);
  17747. + if ((t & mask) == val)
  17748. + return 0;
  17749. +
  17750. + msleep(1);
  17751. + }
  17752. +
  17753. + return -ETIMEDOUT;
  17754. +}
  17755. +
  17756. +static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr,
  17757. + unsigned reg_addr)
  17758. +{
  17759. + u32 t;
  17760. + int err;
  17761. +
  17762. + if (phy_addr >= AR7240_NUM_PHYS)
  17763. + return 0xffff;
  17764. +
  17765. + t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17766. + (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17767. + AR7240_MDIO_CTRL_MASTER_EN |
  17768. + AR7240_MDIO_CTRL_BUSY |
  17769. + AR7240_MDIO_CTRL_CMD_READ;
  17770. +
  17771. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17772. + err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17773. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17774. + if (err)
  17775. + return 0xffff;
  17776. +
  17777. + t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL);
  17778. + return (t & AR7240_MDIO_CTRL_DATA_M);
  17779. +}
  17780. +
  17781. +static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
  17782. + unsigned reg_addr, u16 reg_val)
  17783. +{
  17784. + u32 t;
  17785. + int ret;
  17786. +
  17787. + if (phy_addr >= AR7240_NUM_PHYS)
  17788. + return -EINVAL;
  17789. +
  17790. + t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17791. + (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17792. + AR7240_MDIO_CTRL_MASTER_EN |
  17793. + AR7240_MDIO_CTRL_BUSY |
  17794. + AR7240_MDIO_CTRL_CMD_WRITE |
  17795. + reg_val;
  17796. +
  17797. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17798. + ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17799. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17800. + return ret;
  17801. +}
  17802. +
  17803. +static int ar7240sw_capture_stats(struct ar7240sw *as)
  17804. +{
  17805. + int ret;
  17806. +
  17807. + /* Capture the hardware statistics for all ports */
  17808. + ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0,
  17809. + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
  17810. +
  17811. + /* Wait for the capturing to complete. */
  17812. + ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0,
  17813. + AR7240_MIB_BUSY, 0, 10);
  17814. + return ret;
  17815. +}
  17816. +
  17817. +static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
  17818. +{
  17819. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port),
  17820. + AR7240_PORT_CTRL_STATE_DISABLED);
  17821. +}
  17822. +
  17823. +static int ar7240sw_reset(struct ar7240sw *as)
  17824. +{
  17825. + int ret;
  17826. + int i;
  17827. +
  17828. + /* Set all ports to disabled state. */
  17829. + for (i = 0; i < AR7240_NUM_PORTS; i++)
  17830. + ar7240sw_disable_port(as, i);
  17831. +
  17832. + /* Wait for transmit queues to drain. */
  17833. + msleep(2);
  17834. +
  17835. + /* Reset the switch. */
  17836. + ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL,
  17837. + AR7240_MASK_CTRL_SOFT_RESET);
  17838. +
  17839. + ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL,
  17840. + AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
  17841. + return ret;
  17842. +}
  17843. +
  17844. +static void ar7240sw_setup(struct ar7240sw *as)
  17845. +{
  17846. + /* Enable CPU port, and disable mirror port */
  17847. + ar7240sw_reg_write(as, AR7240_REG_CPU_PORT,
  17848. + AR7240_CPU_PORT_EN |
  17849. + (15 << AR7240_MIRROR_PORT_S));
  17850. +
  17851. + /* Setup TAG priority mapping */
  17852. + ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50);
  17853. +
  17854. + /* Enable ARP frame acknowledge */
  17855. + ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
  17856. +
  17857. + /* Enable Broadcast frames transmitted to the CPU */
  17858. + ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK,
  17859. + AR7240_FLOOD_MASK_BROAD_TO_CPU);
  17860. +
  17861. + /* setup MTU */
  17862. + ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
  17863. + 1536);
  17864. +
  17865. + /* setup Service TAG */
  17866. + ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M,
  17867. + ETH_P_QINQ);
  17868. +}
  17869. +
  17870. +static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port)
  17871. +{
  17872. + u32 ctrl;
  17873. + u32 dest_ports;
  17874. + u32 vlan;
  17875. +
  17876. + ctrl = AR7240_PORT_CTRL_STATE_FORWARD;
  17877. +
  17878. + if (port == AR7240_PORT_CPU) {
  17879. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17880. + AR7240_PORT_STATUS_SPEED_1000 |
  17881. + AR7240_PORT_STATUS_TXFLOW |
  17882. + AR7240_PORT_STATUS_RXFLOW |
  17883. + AR7240_PORT_STATUS_TXMAC |
  17884. + AR7240_PORT_STATUS_RXMAC |
  17885. + AR7240_PORT_STATUS_DUPLEX);
  17886. +
  17887. + /* allow the CPU port to talk to each of the 'real' ports */
  17888. + dest_ports = AR7240_PORT_MASK_BUT(port);
  17889. +
  17890. + /* remove service tag from ingress frames */
  17891. + ctrl |= AR7240_PORT_CTRL_DOUBLE_TAG;
  17892. + } else {
  17893. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17894. + AR7240_PORT_STATUS_LINK_AUTO);
  17895. +
  17896. + /*
  17897. + * allow each of the 'real' ports to only talk to the CPU
  17898. + * port.
  17899. + */
  17900. + dest_ports = AR7240_PORT_MASK(port) |
  17901. + AR7240_PORT_MASK(AR7240_PORT_CPU);
  17902. +
  17903. + /* add service tag to egress frames */
  17904. + ctrl |= (AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG <<
  17905. + AR7240_PORT_CTRL_VLAN_MODE_S);
  17906. + }
  17907. +
  17908. + /* set default VID and and destination ports for this VLAN */
  17909. + vlan = port;
  17910. + vlan |= (dest_ports << AR7240_PORT_VLAN_DEST_PORTS_S);
  17911. +
  17912. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl);
  17913. + ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan);
  17914. +}
  17915. +
  17916. +static char *ar7240_dsa_probe(struct mii_bus *mii, int sw_addr)
  17917. +{
  17918. + struct ar7240sw as;
  17919. + u32 ctrl;
  17920. + u16 phy_id1;
  17921. + u16 phy_id2;
  17922. + u8 ver;
  17923. +
  17924. + ar7240sw_init(&as, mii);
  17925. +
  17926. + ctrl = ar7240sw_reg_read(&as, AR7240_REG_MASK_CTRL);
  17927. +
  17928. + ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
  17929. + if (ver != 1) {
  17930. + pr_err("ar7240_dsa: unsupported chip, ctrl=%08x\n", ctrl);
  17931. + return NULL;
  17932. + }
  17933. +
  17934. + phy_id1 = ar7240sw_phy_read(&as, 0, MII_PHYSID1);
  17935. + phy_id2 = ar7240sw_phy_read(&as, 0, MII_PHYSID2);
  17936. + if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
  17937. + pr_err("ar7240_dsa: unknown phy id '%04x:%04x'\n",
  17938. + phy_id1, phy_id2);
  17939. + return NULL;
  17940. + }
  17941. +
  17942. + return "Atheros AR7240 built-in";
  17943. +}
  17944. +
  17945. +static int ar7240_dsa_setup(struct dsa_switch *ds)
  17946. +{
  17947. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17948. + int i;
  17949. + int ret;
  17950. +
  17951. + ar7240sw_init(as, ds->master_mii_bus);
  17952. +
  17953. + ret = ar7240sw_reset(as);
  17954. + if (ret)
  17955. + return ret;
  17956. +
  17957. + ar7240sw_setup(as);
  17958. +
  17959. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  17960. + if (dsa_is_cpu_port(ds, i) || (ds->phys_port_mask & (1 << i)))
  17961. + ar7240sw_setup_port(as, i);
  17962. + else
  17963. + ar7240sw_disable_port(as, i);
  17964. + }
  17965. +
  17966. + return 0;
  17967. +}
  17968. +
  17969. +static int ar7240_dsa_set_addr(struct dsa_switch *ds, u8 *addr)
  17970. +{
  17971. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17972. + u32 t;
  17973. +
  17974. + t = (addr[4] << 8) | addr[5];
  17975. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
  17976. +
  17977. + t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
  17978. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR1, t);
  17979. +
  17980. + return 0;
  17981. +}
  17982. +
  17983. +static int ar7240_iort_to_phy_addr(int port)
  17984. +{
  17985. + if (port > 0 && port < AR7240_NUM_PORTS)
  17986. + return port - 1;
  17987. +
  17988. + return -EINVAL;
  17989. +}
  17990. +
  17991. +static int ar7240_dsa_phy_read(struct dsa_switch *ds, int port, int regnum)
  17992. +{
  17993. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17994. + int phy_addr;
  17995. +
  17996. + phy_addr = ar7240_iort_to_phy_addr(port);
  17997. + if (phy_addr < 0)
  17998. + return 0xffff;
  17999. +
  18000. + return ar7240sw_phy_read(as, phy_addr, regnum);
  18001. +}
  18002. +
  18003. +static int ar7240_dsa_phy_write(struct dsa_switch *ds, int port, int regnum,
  18004. + u16 val)
  18005. +{
  18006. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18007. + int phy_addr;
  18008. +
  18009. + phy_addr = ar7240_iort_to_phy_addr(port);
  18010. + if (phy_addr < 0)
  18011. + return 0xffff;
  18012. +
  18013. + return ar7240sw_phy_write(as, phy_addr, regnum, val);
  18014. +}
  18015. +
  18016. +static const char *ar7240sw_speed_str(unsigned speed)
  18017. +{
  18018. + switch (speed) {
  18019. + case AR7240_PORT_STATUS_SPEED_10:
  18020. + return "10";
  18021. + case AR7240_PORT_STATUS_SPEED_100:
  18022. + return "100";
  18023. + case AR7240_PORT_STATUS_SPEED_1000:
  18024. + return "1000";
  18025. + }
  18026. +
  18027. + return "????";
  18028. +}
  18029. +
  18030. +static void ar7240_dsa_poll_link(struct dsa_switch *ds)
  18031. +{
  18032. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18033. + int i;
  18034. +
  18035. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  18036. + struct net_device *dev;
  18037. + u32 status;
  18038. + int link;
  18039. + unsigned speed;
  18040. + int duplex;
  18041. +
  18042. + dev = ds->ports[i];
  18043. + if (dev == NULL)
  18044. + continue;
  18045. +
  18046. + link = 0;
  18047. + if (dev->flags & IFF_UP) {
  18048. + status = ar7240sw_reg_read(as,
  18049. + AR7240_REG_PORT_STATUS(i));
  18050. + link = !!(status & AR7240_PORT_STATUS_LINK_UP);
  18051. + }
  18052. +
  18053. + if (!link) {
  18054. + if (netif_carrier_ok(dev)) {
  18055. + pr_info("%s: link down\n", dev->name);
  18056. + netif_carrier_off(dev);
  18057. + }
  18058. + continue;
  18059. + }
  18060. +
  18061. + speed = (status & AR7240_PORT_STATUS_SPEED_M);
  18062. + duplex = (status & AR7240_PORT_STATUS_DUPLEX) ? 1 : 0;
  18063. + if (!netif_carrier_ok(dev)) {
  18064. + pr_info("%s: link up, %sMb/s, %s duplex",
  18065. + dev->name,
  18066. + ar7240sw_speed_str(speed),
  18067. + duplex ? "full" : "half");
  18068. + netif_carrier_on(dev);
  18069. + }
  18070. + }
  18071. +}
  18072. +
  18073. +static const struct ar7240sw_hw_stat ar7240_hw_stats[] = {
  18074. + { "rx_broadcast" , 4, AR7240_STATS_RXBROAD, },
  18075. + { "rx_pause" , 4, AR7240_STATS_RXPAUSE, },
  18076. + { "rx_multicast" , 4, AR7240_STATS_RXMULTI, },
  18077. + { "rx_fcs_error" , 4, AR7240_STATS_RXFCSERR, },
  18078. + { "rx_align_error" , 4, AR7240_STATS_RXALIGNERR, },
  18079. + { "rx_undersize" , 4, AR7240_STATS_RXRUNT, },
  18080. + { "rx_fragments" , 4, AR7240_STATS_RXFRAGMENT, },
  18081. + { "rx_64bytes" , 4, AR7240_STATS_RX64BYTE, },
  18082. + { "rx_65_127bytes" , 4, AR7240_STATS_RX128BYTE, },
  18083. + { "rx_128_255bytes" , 4, AR7240_STATS_RX256BYTE, },
  18084. + { "rx_256_511bytes" , 4, AR7240_STATS_RX512BYTE, },
  18085. + { "rx_512_1023bytes" , 4, AR7240_STATS_RX1024BYTE, },
  18086. + { "rx_1024_1518bytes" , 4, AR7240_STATS_RX1518BYTE, },
  18087. + { "rx_1519_max_bytes" , 4, AR7240_STATS_RXMAXBYTE, },
  18088. + { "rx_oversize" , 4, AR7240_STATS_RXTOOLONG, },
  18089. + { "rx_good_bytes" , 8, AR7240_STATS_RXGOODBYTE, },
  18090. + { "rx_bad_bytes" , 8, AR7240_STATS_RXBADBYTE, },
  18091. + { "rx_overflow" , 4, AR7240_STATS_RXOVERFLOW, },
  18092. + { "filtered" , 4, AR7240_STATS_FILTERED, },
  18093. + { "tx_broadcast" , 4, AR7240_STATS_TXBROAD, },
  18094. + { "tx_pause" , 4, AR7240_STATS_TXPAUSE, },
  18095. + { "tx_multicast" , 4, AR7240_STATS_TXMULTI, },
  18096. + { "tx_underrun" , 4, AR7240_STATS_TXUNDERRUN, },
  18097. + { "tx_64bytes" , 4, AR7240_STATS_TX64BYTE, },
  18098. + { "tx_65_127bytes" , 4, AR7240_STATS_TX128BYTE, },
  18099. + { "tx_128_255bytes" , 4, AR7240_STATS_TX256BYTE, },
  18100. + { "tx_256_511bytes" , 4, AR7240_STATS_TX512BYTE, },
  18101. + { "tx_512_1023bytes" , 4, AR7240_STATS_TX1024BYTE, },
  18102. + { "tx_1024_1518bytes" , 4, AR7240_STATS_TX1518BYTE, },
  18103. + { "tx_1519_max_bytes" , 4, AR7240_STATS_TXMAXBYTE, },
  18104. + { "tx_oversize" , 4, AR7240_STATS_TXOVERSIZE, },
  18105. + { "tx_bytes" , 8, AR7240_STATS_TXBYTE, },
  18106. + { "tx_collisions" , 4, AR7240_STATS_TXCOLLISION, },
  18107. + { "tx_abort_collisions" , 4, AR7240_STATS_TXABORTCOL, },
  18108. + { "tx_multi_collisions" , 4, AR7240_STATS_TXMULTICOL, },
  18109. + { "tx_single_collisions", 4, AR7240_STATS_TXSINGLECOL, },
  18110. + { "tx_excessive_deferred", 4, AR7240_STATS_TXEXCDEFER, },
  18111. + { "tx_deferred" , 4, AR7240_STATS_TXDEFER, },
  18112. + { "tx_late_collisions" , 4, AR7240_STATS_TXLATECOL, },
  18113. +};
  18114. +
  18115. +static void ar7240_dsa_get_strings(struct dsa_switch *ds, int port,
  18116. + uint8_t *data)
  18117. +{
  18118. + int i;
  18119. +
  18120. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  18121. + memcpy(data + i * ETH_GSTRING_LEN,
  18122. + ar7240_hw_stats[i].string, ETH_GSTRING_LEN);
  18123. + }
  18124. +}
  18125. +
  18126. +static void ar7240_dsa_get_ethtool_stats(struct dsa_switch *ds, int port,
  18127. + uint64_t *data)
  18128. +{
  18129. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18130. + int err;
  18131. + int i;
  18132. +
  18133. + mutex_lock(&as->stats_mutex);
  18134. +
  18135. + err = ar7240sw_capture_stats(as);
  18136. + if (err)
  18137. + goto unlock;
  18138. +
  18139. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  18140. + const struct ar7240sw_hw_stat *s = &ar7240_hw_stats[i];
  18141. + u32 reg = AR7240_REG_STATS_BASE(port);
  18142. + u32 low;
  18143. + u32 high;
  18144. +
  18145. + low = ar7240sw_reg_read(as, reg + s->reg);
  18146. + if (s->sizeof_stat == 8)
  18147. + high = ar7240sw_reg_read(as, reg + s->reg);
  18148. + else
  18149. + high = 0;
  18150. +
  18151. + data[i] = (((u64) high) << 32) | low;
  18152. + }
  18153. +
  18154. + unlock:
  18155. + mutex_unlock(&as->stats_mutex);
  18156. +}
  18157. +
  18158. +static int ar7240_dsa_get_sset_count(struct dsa_switch *ds)
  18159. +{
  18160. + return ARRAY_SIZE(ar7240_hw_stats);
  18161. +}
  18162. +
  18163. +static struct dsa_switch_driver ar7240_dsa_driver = {
  18164. + .tag_protocol = htons(ETH_P_QINQ),
  18165. + .priv_size = sizeof(struct ar7240sw),
  18166. + .probe = ar7240_dsa_probe,
  18167. + .setup = ar7240_dsa_setup,
  18168. + .set_addr = ar7240_dsa_set_addr,
  18169. + .phy_read = ar7240_dsa_phy_read,
  18170. + .phy_write = ar7240_dsa_phy_write,
  18171. + .poll_link = ar7240_dsa_poll_link,
  18172. + .get_strings = ar7240_dsa_get_strings,
  18173. + .get_ethtool_stats = ar7240_dsa_get_ethtool_stats,
  18174. + .get_sset_count = ar7240_dsa_get_sset_count,
  18175. +};
  18176. +
  18177. +int __init dsa_ar7240_init(void)
  18178. +{
  18179. + register_switch_driver(&ar7240_dsa_driver);
  18180. + return 0;
  18181. +}
  18182. +module_init(dsa_ar7240_init);
  18183. +
  18184. +void __exit dsa_ar7240_cleanup(void)
  18185. +{
  18186. + unregister_switch_driver(&ar7240_dsa_driver);
  18187. +}
  18188. +module_exit(dsa_ar7240_cleanup);
  18189. diff -Nur linux-2.6.36.orig/net/dsa/mv88e6063.c linux-2.6.36/net/dsa/mv88e6063.c
  18190. --- linux-2.6.36.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100
  18191. +++ linux-2.6.36/net/dsa/mv88e6063.c 2010-12-17 18:34:51.000000000 +0100
  18192. @@ -0,0 +1,294 @@
  18193. +/*
  18194. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips
  18195. + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  18196. + *
  18197. + * This driver was base on: net/dsa/mv88e6060.c
  18198. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips
  18199. + * Copyright (c) 2008-2009 Marvell Semiconductor
  18200. + *
  18201. + * This program is free software; you can redistribute it and/or modify
  18202. + * it under the terms of the GNU General Public License as published by
  18203. + * the Free Software Foundation; either version 2 of the License, or
  18204. + * (at your option) any later version.
  18205. + */
  18206. +
  18207. +#include <linux/list.h>
  18208. +#include <linux/netdevice.h>
  18209. +#include <linux/phy.h>
  18210. +#include "dsa_priv.h"
  18211. +
  18212. +#define REG_BASE 0x10
  18213. +#define REG_PHY(p) (REG_BASE + (p))
  18214. +#define REG_PORT(p) (REG_BASE + 8 + (p))
  18215. +#define REG_GLOBAL (REG_BASE + 0x0f)
  18216. +#define NUM_PORTS 7
  18217. +
  18218. +static int reg_read(struct dsa_switch *ds, int addr, int reg)
  18219. +{
  18220. + return mdiobus_read(ds->master_mii_bus, addr, reg);
  18221. +}
  18222. +
  18223. +#define REG_READ(addr, reg) \
  18224. + ({ \
  18225. + int __ret; \
  18226. + \
  18227. + __ret = reg_read(ds, addr, reg); \
  18228. + if (__ret < 0) \
  18229. + return __ret; \
  18230. + __ret; \
  18231. + })
  18232. +
  18233. +
  18234. +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
  18235. +{
  18236. + return mdiobus_write(ds->master_mii_bus, addr, reg, val);
  18237. +}
  18238. +
  18239. +#define REG_WRITE(addr, reg, val) \
  18240. + ({ \
  18241. + int __ret; \
  18242. + \
  18243. + __ret = reg_write(ds, addr, reg, val); \
  18244. + if (__ret < 0) \
  18245. + return __ret; \
  18246. + })
  18247. +
  18248. +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr)
  18249. +{
  18250. + int ret;
  18251. +
  18252. + ret = mdiobus_read(bus, REG_PORT(0), 0x03);
  18253. + if (ret >= 0) {
  18254. + ret &= 0xfff0;
  18255. + if (ret == 0x1530)
  18256. + return "Marvell 88E6063";
  18257. + }
  18258. +
  18259. + return NULL;
  18260. +}
  18261. +
  18262. +static int mv88e6063_switch_reset(struct dsa_switch *ds)
  18263. +{
  18264. + int i;
  18265. + int ret;
  18266. +
  18267. + /*
  18268. + * Set all ports to the disabled state.
  18269. + */
  18270. + for (i = 0; i < NUM_PORTS; i++) {
  18271. + ret = REG_READ(REG_PORT(i), 0x04);
  18272. + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
  18273. + }
  18274. +
  18275. + /*
  18276. + * Wait for transmit queues to drain.
  18277. + */
  18278. + msleep(2);
  18279. +
  18280. + /*
  18281. + * Reset the switch.
  18282. + */
  18283. + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130);
  18284. +
  18285. + /*
  18286. + * Wait up to one second for reset to complete.
  18287. + */
  18288. + for (i = 0; i < 1000; i++) {
  18289. + ret = REG_READ(REG_GLOBAL, 0x00);
  18290. + if ((ret & 0x8000) == 0x0000)
  18291. + break;
  18292. +
  18293. + msleep(1);
  18294. + }
  18295. + if (i == 1000)
  18296. + return -ETIMEDOUT;
  18297. +
  18298. + return 0;
  18299. +}
  18300. +
  18301. +static int mv88e6063_setup_global(struct dsa_switch *ds)
  18302. +{
  18303. + /*
  18304. + * Disable discarding of frames with excessive collisions,
  18305. + * set the maximum frame size to 1536 bytes, and mask all
  18306. + * interrupt sources.
  18307. + */
  18308. + REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
  18309. +
  18310. + /*
  18311. + * Enable automatic address learning, set the address
  18312. + * database size to 1024 entries, and set the default aging
  18313. + * time to 5 minutes.
  18314. + */
  18315. + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
  18316. +
  18317. + return 0;
  18318. +}
  18319. +
  18320. +static int mv88e6063_setup_port(struct dsa_switch *ds, int p)
  18321. +{
  18322. + int addr = REG_PORT(p);
  18323. +
  18324. + /*
  18325. + * Do not force flow control, disable Ingress and Egress
  18326. + * Header tagging, disable VLAN tunneling, and set the port
  18327. + * state to Forwarding. Additionally, if this is the CPU
  18328. + * port, enable Ingress and Egress Trailer tagging mode.
  18329. + */
  18330. + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003);
  18331. +
  18332. + /*
  18333. + * Port based VLAN map: give each port its own address
  18334. + * database, allow the CPU port to talk to each of the 'real'
  18335. + * ports, and allow each of the 'real' ports to only talk to
  18336. + * the CPU port.
  18337. + */
  18338. + REG_WRITE(addr, 0x06,
  18339. + ((p & 0xf) << 12) |
  18340. + (dsa_is_cpu_port(ds, p) ?
  18341. + ds->phys_port_mask :
  18342. + (1 << ds->dst->cpu_port)));
  18343. +
  18344. + /*
  18345. + * Port Association Vector: when learning source addresses
  18346. + * of packets, add the address to the address database using
  18347. + * a port bitmap that has only the bit for this port set and
  18348. + * the other bits clear.
  18349. + */
  18350. + REG_WRITE(addr, 0x0b, 1 << p);
  18351. +
  18352. + return 0;
  18353. +}
  18354. +
  18355. +static int mv88e6063_setup(struct dsa_switch *ds)
  18356. +{
  18357. + int i;
  18358. + int ret;
  18359. +
  18360. + ret = mv88e6063_switch_reset(ds);
  18361. + if (ret < 0)
  18362. + return ret;
  18363. +
  18364. + /* @@@ initialise atu */
  18365. +
  18366. + ret = mv88e6063_setup_global(ds);
  18367. + if (ret < 0)
  18368. + return ret;
  18369. +
  18370. + for (i = 0; i < NUM_PORTS; i++) {
  18371. + ret = mv88e6063_setup_port(ds, i);
  18372. + if (ret < 0)
  18373. + return ret;
  18374. + }
  18375. +
  18376. + return 0;
  18377. +}
  18378. +
  18379. +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr)
  18380. +{
  18381. + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
  18382. + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
  18383. + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
  18384. +
  18385. + return 0;
  18386. +}
  18387. +
  18388. +static int mv88e6063_port_to_phy_addr(int port)
  18389. +{
  18390. + if (port >= 0 && port <= NUM_PORTS)
  18391. + return REG_PHY(port);
  18392. + return -1;
  18393. +}
  18394. +
  18395. +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum)
  18396. +{
  18397. + int addr;
  18398. +
  18399. + addr = mv88e6063_port_to_phy_addr(port);
  18400. + if (addr == -1)
  18401. + return 0xffff;
  18402. +
  18403. + return reg_read(ds, addr, regnum);
  18404. +}
  18405. +
  18406. +static int
  18407. +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
  18408. +{
  18409. + int addr;
  18410. +
  18411. + addr = mv88e6063_port_to_phy_addr(port);
  18412. + if (addr == -1)
  18413. + return 0xffff;
  18414. +
  18415. + return reg_write(ds, addr, regnum, val);
  18416. +}
  18417. +
  18418. +static void mv88e6063_poll_link(struct dsa_switch *ds)
  18419. +{
  18420. + int i;
  18421. +
  18422. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  18423. + struct net_device *dev;
  18424. + int uninitialized_var(port_status);
  18425. + int link;
  18426. + int speed;
  18427. + int duplex;
  18428. + int fc;
  18429. +
  18430. + dev = ds->ports[i];
  18431. + if (dev == NULL)
  18432. + continue;
  18433. +
  18434. + link = 0;
  18435. + if (dev->flags & IFF_UP) {
  18436. + port_status = reg_read(ds, REG_PORT(i), 0x00);
  18437. + if (port_status < 0)
  18438. + continue;
  18439. +
  18440. + link = !!(port_status & 0x1000);
  18441. + }
  18442. +
  18443. + if (!link) {
  18444. + if (netif_carrier_ok(dev)) {
  18445. + printk(KERN_INFO "%s: link down\n", dev->name);
  18446. + netif_carrier_off(dev);
  18447. + }
  18448. + continue;
  18449. + }
  18450. +
  18451. + speed = (port_status & 0x0100) ? 100 : 10;
  18452. + duplex = (port_status & 0x0200) ? 1 : 0;
  18453. + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
  18454. +
  18455. + if (!netif_carrier_ok(dev)) {
  18456. + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
  18457. + "flow control %sabled\n", dev->name,
  18458. + speed, duplex ? "full" : "half",
  18459. + fc ? "en" : "dis");
  18460. + netif_carrier_on(dev);
  18461. + }
  18462. + }
  18463. +}
  18464. +
  18465. +static struct dsa_switch_driver mv88e6063_switch_driver = {
  18466. + .tag_protocol = htons(ETH_P_TRAILER),
  18467. + .probe = mv88e6063_probe,
  18468. + .setup = mv88e6063_setup,
  18469. + .set_addr = mv88e6063_set_addr,
  18470. + .phy_read = mv88e6063_phy_read,
  18471. + .phy_write = mv88e6063_phy_write,
  18472. + .poll_link = mv88e6063_poll_link,
  18473. +};
  18474. +
  18475. +static int __init mv88e6063_init(void)
  18476. +{
  18477. + register_switch_driver(&mv88e6063_switch_driver);
  18478. + return 0;
  18479. +}
  18480. +module_init(mv88e6063_init);
  18481. +
  18482. +static void __exit mv88e6063_cleanup(void)
  18483. +{
  18484. + unregister_switch_driver(&mv88e6063_switch_driver);
  18485. +}
  18486. +module_exit(mv88e6063_cleanup);
  18487. diff -Nur linux-2.6.36.orig/net/dsa/tag_qinq.c linux-2.6.36/net/dsa/tag_qinq.c
  18488. --- linux-2.6.36.orig/net/dsa/tag_qinq.c 1970-01-01 01:00:00.000000000 +0100
  18489. +++ linux-2.6.36/net/dsa/tag_qinq.c 2010-12-17 18:34:51.000000000 +0100
  18490. @@ -0,0 +1,127 @@
  18491. +/*
  18492. + * net/dsa/tag_qinq.c - QinQ tag format handling
  18493. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  18494. + *
  18495. + * This file was based on:
  18496. + * net/dsa/tag_edsa.c - Ethertype DSA tagging
  18497. + * Copyright (c) 2008-2009 Marvell Semiconductor
  18498. + *
  18499. + * This program is free software; you can redistribute it and/or modify
  18500. + * it under the terms of the GNU General Public License as published by
  18501. + * the Free Software Foundation; either version 2 of the License, or
  18502. + * (at your option) any later version.
  18503. + */
  18504. +
  18505. +#include <linux/etherdevice.h>
  18506. +#include <linux/list.h>
  18507. +#include <linux/netdevice.h>
  18508. +#include <linux/if_vlan.h>
  18509. +
  18510. +#include "dsa_priv.h"
  18511. +
  18512. +netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev)
  18513. +{
  18514. + struct dsa_slave_priv *p = netdev_priv(dev);
  18515. + struct vlan_ethhdr *veth;
  18516. + unsigned int len;
  18517. + int ret;
  18518. +
  18519. + if (skb_cow_head(skb, VLAN_HLEN) < 0)
  18520. + goto out_free_skb;
  18521. +
  18522. + veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
  18523. +
  18524. + /* Move the mac addresses to the beginning of the new header. */
  18525. + memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
  18526. + skb->mac_header -= VLAN_HLEN;
  18527. +
  18528. + /* setup VLAN header fields */
  18529. + veth->h_vlan_proto = htons(ETH_P_QINQ);
  18530. + veth->h_vlan_TCI = htons(p->port);
  18531. +
  18532. + len = skb->len;
  18533. + skb->protocol = htons(ETH_P_QINQ);
  18534. + skb->dev = p->parent->dst->master_netdev;
  18535. +
  18536. + ret = dev_queue_xmit(skb);
  18537. + if (unlikely(ret != NET_XMIT_SUCCESS))
  18538. + goto out_dropped;
  18539. +
  18540. + dev->stats.tx_packets++;
  18541. + dev->stats.tx_bytes += len;
  18542. +
  18543. + return NETDEV_TX_OK;
  18544. +
  18545. + out_free_skb:
  18546. + kfree_skb(skb);
  18547. + out_dropped:
  18548. + dev->stats.tx_dropped++;
  18549. + return NETDEV_TX_OK;
  18550. +}
  18551. +
  18552. +static int qinq_rcv(struct sk_buff *skb, struct net_device *dev,
  18553. + struct packet_type *pt, struct net_device *orig_dev)
  18554. +{
  18555. + struct dsa_switch_tree *dst;
  18556. + struct dsa_switch *ds;
  18557. + struct vlan_hdr *vhdr;
  18558. + int source_port;
  18559. +
  18560. + dst = dev->dsa_ptr;
  18561. + if (unlikely(dst == NULL))
  18562. + goto out_drop;
  18563. + ds = dst->ds[0];
  18564. +
  18565. + skb = skb_unshare(skb, GFP_ATOMIC);
  18566. + if (skb == NULL)
  18567. + goto out;
  18568. +
  18569. + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
  18570. + goto out_drop;
  18571. +
  18572. + vhdr = (struct vlan_hdr *)skb->data;
  18573. + source_port = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
  18574. + if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
  18575. + goto out_drop;
  18576. +
  18577. + /* Remove the outermost VLAN tag and update checksum. */
  18578. + skb_pull_rcsum(skb, VLAN_HLEN);
  18579. + memmove(skb->data - ETH_HLEN,
  18580. + skb->data - ETH_HLEN - VLAN_HLEN,
  18581. + 2 * ETH_ALEN);
  18582. +
  18583. + skb->dev = ds->ports[source_port];
  18584. + skb_push(skb, ETH_HLEN);
  18585. + skb->pkt_type = PACKET_HOST;
  18586. + skb->protocol = eth_type_trans(skb, skb->dev);
  18587. +
  18588. + skb->dev->stats.rx_packets++;
  18589. + skb->dev->stats.rx_bytes += skb->len;
  18590. +
  18591. + netif_receive_skb(skb);
  18592. +
  18593. + return 0;
  18594. +
  18595. + out_drop:
  18596. + kfree_skb(skb);
  18597. + out:
  18598. + return 0;
  18599. +}
  18600. +
  18601. +static struct packet_type qinq_packet_type __read_mostly = {
  18602. + .type = cpu_to_be16(ETH_P_QINQ),
  18603. + .func = qinq_rcv,
  18604. +};
  18605. +
  18606. +static int __init qinq_init_module(void)
  18607. +{
  18608. + dev_add_pack(&qinq_packet_type);
  18609. + return 0;
  18610. +}
  18611. +module_init(qinq_init_module);
  18612. +
  18613. +static void __exit qinq_cleanup_module(void)
  18614. +{
  18615. + dev_remove_pack(&qinq_packet_type);
  18616. +}
  18617. +module_exit(qinq_cleanup_module);