rb4xx.patch 484 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430
  1. diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig
  2. --- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200
  3. +++ linux-2.6.39/arch/mips/Kconfig 2011-05-27 14:36:50.000000000 +0200
  4. @@ -84,6 +84,23 @@
  5. help
  6. Support for the Atheros AR71XX/AR724X/AR913X SoCs.
  7. +config ATHEROS_AR71XX
  8. + bool "Atheros AR71xx based boards"
  9. + select CEVT_R4K
  10. + select CSRC_R4K
  11. + select DMA_NONCOHERENT
  12. + select HW_HAS_PCI
  13. + select IRQ_CPU
  14. + select ARCH_REQUIRE_GPIOLIB
  15. + select SYS_HAS_CPU_MIPS32_R1
  16. + select SYS_HAS_CPU_MIPS32_R2
  17. + select SYS_SUPPORTS_32BIT_KERNEL
  18. + select SYS_SUPPORTS_BIG_ENDIAN
  19. + select SYS_HAS_EARLY_PRINTK
  20. + select MIPS_MACHINE
  21. + help
  22. + Support for Atheros AR71xx based boards.
  23. +
  24. config BCM47XX
  25. bool "Broadcom BCM47XX based boards"
  26. select CEVT_R4K
  27. @@ -740,6 +757,7 @@
  28. source "arch/mips/alchemy/Kconfig"
  29. source "arch/mips/ath79/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. diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile
  35. --- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200
  36. +++ linux-2.6.39/arch/mips/Makefile 2011-05-27 14:36:50.000000000 +0200
  37. @@ -158,6 +158,13 @@
  38. endif
  39. cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
  40. +#
  41. +# Atheros AR71xx
  42. +#
  43. +core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
  44. +cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
  45. +load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
  46. +
  47. cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
  48. cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
  49. cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
  50. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig
  51. --- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  52. +++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-05-27 14:36:50.000000000 +0200
  53. @@ -0,0 +1,264 @@
  54. +if ATHEROS_AR71XX
  55. +
  56. +menu "Atheros AR71xx machine selection"
  57. +
  58. +config AR71XX_MACH_AP81
  59. + bool "Atheros AP81 board support"
  60. + select AR71XX_DEV_M25P80
  61. + select AR71XX_DEV_AR913X_WMAC
  62. + select AR71XX_DEV_GPIO_BUTTONS
  63. + select AR71XX_DEV_LEDS_GPIO
  64. + select AR71XX_DEV_USB
  65. + default n
  66. +
  67. +config AR71XX_MACH_AP83
  68. + bool "Atheros AP83 board support"
  69. + select AR71XX_DEV_AR913X_WMAC
  70. + select AR71XX_DEV_GPIO_BUTTONS
  71. + select AR71XX_DEV_LEDS_GPIO
  72. + select AR71XX_DEV_USB
  73. + default n
  74. +
  75. +config AR71XX_MACH_DIR_600_A1
  76. + bool "D-Link DIR-600 rev. A1 support"
  77. + select AR71XX_DEV_AP91_ETH
  78. + select AR71XX_DEV_AP91_PCI if PCI
  79. + select AR71XX_DEV_M25P80
  80. + select AR71XX_DEV_GPIO_BUTTONS
  81. + select AR71XX_DEV_LEDS_GPIO
  82. + select AR71XX_NVRAM
  83. + default n
  84. +
  85. +config AR71XX_MACH_DIR_615_C1
  86. + bool "D-Link DIR-615 rev. C1 support"
  87. + select AR71XX_DEV_M25P80
  88. + select AR71XX_DEV_AR913X_WMAC
  89. + select AR71XX_DEV_GPIO_BUTTONS
  90. + select AR71XX_DEV_LEDS_GPIO
  91. + select AR71XX_NVRAM
  92. + default n
  93. +
  94. +config AR71XX_MACH_DIR_825_B1
  95. + bool "D-Link DIR-825 rev. B1 board support"
  96. + select AR71XX_DEV_M25P80
  97. + select AR71XX_DEV_AP94_PCI if PCI
  98. + select AR71XX_DEV_GPIO_BUTTONS
  99. + select AR71XX_DEV_LEDS_GPIO
  100. + select AR71XX_DEV_USB
  101. + default n
  102. +
  103. +config AR71XX_MACH_PB42
  104. + bool "Atheros PB42 board support"
  105. + select AR71XX_DEV_M25P80
  106. + select AR71XX_DEV_GPIO_BUTTONS
  107. + select AR71XX_DEV_PB42_PCI if PCI
  108. + default n
  109. +
  110. +config AR71XX_MACH_PB44
  111. + bool "Atheros PB44 board support"
  112. + select AR71XX_DEV_GPIO_BUTTONS
  113. + select AR71XX_DEV_PB42_PCI if PCI
  114. + select AR71XX_DEV_LEDS_GPIO
  115. + select AR71XX_DEV_USB
  116. + default n
  117. +
  118. +config AR71XX_MACH_PB92
  119. + bool "Atheros PB92 board support"
  120. + select AR71XX_DEV_GPIO_BUTTONS
  121. + select AR71XX_DEV_PB9X_PCI if PCI
  122. + select AR71XX_DEV_LEDS_GPIO
  123. + select AR71XX_DEV_USB
  124. + default n
  125. +
  126. +config AR71XX_MACH_AW_NR580
  127. + bool "AzureWave AW-NR580 board support"
  128. + select AR71XX_DEV_M25P80
  129. + select AR71XX_DEV_GPIO_BUTTONS
  130. + select AR71XX_DEV_PB42_PCI if PCI
  131. + select AR71XX_DEV_LEDS_GPIO
  132. + default n
  133. +
  134. +config AR71XX_MACH_WZR_HP_G300NH
  135. + bool "Buffalo WZR-HP-G300NH board support"
  136. + select AR71XX_DEV_AR913X_WMAC
  137. + select AR71XX_DEV_GPIO_BUTTONS
  138. + select AR71XX_DEV_LEDS_GPIO
  139. + select AR71XX_DEV_USB
  140. + default y
  141. +
  142. +config AR71XX_MACH_WP543
  143. + bool "Compex WP543/WPJ543 board support"
  144. + select MYLOADER
  145. + select AR71XX_DEV_M25P80
  146. + select AR71XX_DEV_GPIO_BUTTONS
  147. + select AR71XX_DEV_PB42_PCI if PCI
  148. + select AR71XX_DEV_LEDS_GPIO
  149. + select AR71XX_DEV_USB
  150. + default n
  151. +
  152. +config AR71XX_MACH_WRT160NL
  153. + bool "Linksys WRT160NL board support"
  154. + select AR71XX_DEV_M25P80
  155. + select AR71XX_DEV_AR913X_WMAC
  156. + select AR71XX_DEV_GPIO_BUTTONS
  157. + select AR71XX_DEV_LEDS_GPIO
  158. + select AR71XX_DEV_USB
  159. + select AR71XX_NVRAM
  160. + default n
  161. +
  162. +config AR71XX_MACH_WRT400N
  163. + bool "Linksys WRT400N board support"
  164. + select AR71XX_DEV_AP94_PCI if PCI
  165. + select AR71XX_DEV_M25P80
  166. + select AR71XX_DEV_GPIO_BUTTONS
  167. + select AR71XX_DEV_LEDS_GPIO
  168. + default n
  169. +
  170. +config AR71XX_MACH_RB4XX
  171. + bool "MikroTik RouterBOARD 4xx series support"
  172. + select AR71XX_DEV_GPIO_BUTTONS
  173. + select AR71XX_DEV_LEDS_GPIO
  174. + select AR71XX_DEV_USB
  175. + default n
  176. +
  177. +config AR71XX_MACH_RB750
  178. + bool "MikroTik RouterBOARD 750 support"
  179. + select AR71XX_DEV_AP91_ETH
  180. + default n
  181. +
  182. +config AR71XX_MACH_WNDR3700
  183. + bool "NETGEAR WNDR3700 board support"
  184. + select AR71XX_DEV_M25P80
  185. + select AR71XX_DEV_AP94_PCI if PCI
  186. + select AR71XX_DEV_GPIO_BUTTONS
  187. + select AR71XX_DEV_LEDS_GPIO
  188. + select AR71XX_DEV_USB
  189. + default n
  190. +
  191. +config AR71XX_MACH_WNR2000
  192. + bool "NETGEAR WNR2000 board support"
  193. + select AR71XX_DEV_M25P80
  194. + select AR71XX_DEV_AR913X_WMAC
  195. + select AR71XX_DEV_GPIO_BUTTONS
  196. + select AR71XX_DEV_LEDS_GPIO
  197. + default n
  198. +
  199. +config AR71XX_MACH_MZK_W04NU
  200. + bool "Planex MZK-W04NU board support"
  201. + select AR71XX_DEV_M25P80
  202. + select AR71XX_DEV_AR913X_WMAC
  203. + select AR71XX_DEV_GPIO_BUTTONS
  204. + select AR71XX_DEV_LEDS_GPIO
  205. + select AR71XX_DEV_USB
  206. + default n
  207. +
  208. +config AR71XX_MACH_MZK_W300NH
  209. + bool "Planex MZK-W300NH board support"
  210. + select AR71XX_DEV_M25P80
  211. + select AR71XX_DEV_AR913X_WMAC
  212. + select AR71XX_DEV_GPIO_BUTTONS
  213. + select AR71XX_DEV_LEDS_GPIO
  214. + default n
  215. +
  216. +config AR71XX_MACH_NBG460N
  217. + bool "Zyxel NBG460N/550N/550NH board support"
  218. + select AR71XX_DEV_M25P80
  219. + select AR71XX_DEV_AR913X_WMAC
  220. + select AR71XX_DEV_GPIO_BUTTONS
  221. + select AR71XX_DEV_LEDS_GPIO
  222. + default n
  223. +
  224. +config AR71XX_MACH_TL_WR741ND
  225. + bool "TP-LINK TL-WR741ND support"
  226. + select AR71XX_DEV_M25P80
  227. + select AR71XX_DEV_AP91_ETH
  228. + select AR71XX_DEV_AP91_PCI if PCI
  229. + select AR71XX_DEV_GPIO_BUTTONS
  230. + select AR71XX_DEV_LEDS_GPIO
  231. + default n
  232. +
  233. +config AR71XX_MACH_TL_WR841N_V1
  234. + bool "TP-LINK TL-WR841N v1 support"
  235. + select AR71XX_DEV_M25P80
  236. + select AR71XX_DEV_PB42_PCI if PCI
  237. + select AR71XX_DEV_DSA
  238. + select AR71XX_DEV_GPIO_BUTTONS
  239. + select AR71XX_DEV_LEDS_GPIO
  240. + default n
  241. +
  242. +config AR71XX_MACH_TL_WR941ND
  243. + bool "TP-LINK TL-WR941ND support"
  244. + select AR71XX_DEV_M25P80
  245. + select AR71XX_DEV_AR913X_WMAC
  246. + select AR71XX_DEV_DSA
  247. + select AR71XX_DEV_GPIO_BUTTONS
  248. + select AR71XX_DEV_LEDS_GPIO
  249. + default n
  250. +
  251. +config AR71XX_MACH_TL_WR1043ND
  252. + bool "TP-LINK TL-WR1043ND support"
  253. + select AR71XX_DEV_M25P80
  254. + select AR71XX_DEV_AR913X_WMAC
  255. + select AR71XX_DEV_GPIO_BUTTONS
  256. + select AR71XX_DEV_LEDS_GPIO
  257. + select AR71XX_DEV_USB
  258. + default n
  259. +
  260. +config AR71XX_MACH_TEW_632BRP
  261. + bool "TRENDnet TEW-632BRP support"
  262. + select AR71XX_DEV_M25P80
  263. + select AR71XX_DEV_AR913X_WMAC
  264. + select AR71XX_DEV_GPIO_BUTTONS
  265. + select AR71XX_DEV_LEDS_GPIO
  266. + select AR71XX_NVRAM
  267. + default n
  268. +
  269. +config AR71XX_MACH_UBNT
  270. + bool "Ubiquiti AR71xx based boards support"
  271. + select AR71XX_DEV_M25P80
  272. + select AR71XX_DEV_AP91_PCI if PCI
  273. + select AR71XX_DEV_GPIO_BUTTONS
  274. + select AR71XX_DEV_LEDS_GPIO
  275. + select AR71XX_DEV_PB42_PCI if PCI
  276. + select AR71XX_DEV_USB
  277. + default n
  278. +
  279. +endmenu
  280. +
  281. +config AR71XX_DEV_M25P80
  282. + def_bool n
  283. +
  284. +config AR71XX_DEV_AP91_PCI
  285. + def_bool n
  286. +
  287. +config AR71XX_DEV_AP91_ETH
  288. + def_bool n
  289. +
  290. +config AR71XX_DEV_AP94_PCI
  291. + def_bool n
  292. +
  293. +config AR71XX_DEV_AR913X_WMAC
  294. + def_bool n
  295. +
  296. +config AR71XX_DEV_DSA
  297. + def_bool n
  298. +
  299. +config AR71XX_DEV_GPIO_BUTTONS
  300. + def_bool n
  301. +
  302. +config AR71XX_DEV_LEDS_GPIO
  303. + def_bool n
  304. +
  305. +config AR71XX_DEV_PB42_PCI
  306. + def_bool n
  307. +
  308. +config AR71XX_DEV_PB9X_PCI
  309. + def_bool n
  310. +
  311. +config AR71XX_DEV_USB
  312. + def_bool n
  313. +
  314. +config AR71XX_NVRAM
  315. + def_bool n
  316. +
  317. +endif
  318. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile
  319. --- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  320. +++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-05-27 14:36:50.000000000 +0200
  321. @@ -0,0 +1,54 @@
  322. +#
  323. +# Makefile for the Atheros AR71xx SoC specific parts of the kernel
  324. +#
  325. +# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  326. +# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  327. +#
  328. +# This program is free software; you can redistribute it and/or modify it
  329. +# under the terms of the GNU General Public License version 2 as published
  330. +# by the Free Software Foundation.
  331. +
  332. +obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o
  333. +
  334. +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  335. +obj-$(CONFIG_PCI) += pci.o
  336. +
  337. +obj-$(CONFIG_AR71XX_DEV_AP91_ETH) += dev-ap91-eth.o
  338. +obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o
  339. +obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o
  340. +obj-$(CONFIG_AR71XX_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
  341. +obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o
  342. +obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
  343. +obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o
  344. +obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o
  345. +obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o
  346. +obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o
  347. +obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o
  348. +
  349. +obj-$(CONFIG_AR71XX_NVRAM) += nvram.o
  350. +
  351. +obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o
  352. +obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o
  353. +obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o
  354. +obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o
  355. +obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o
  356. +obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o
  357. +obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o
  358. +obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o
  359. +obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o
  360. +obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o
  361. +obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o
  362. +obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o
  363. +obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o
  364. +obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o
  365. +obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o
  366. +obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o
  367. +obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o
  368. +obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o
  369. +obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o
  370. +obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o
  371. +obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o
  372. +obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o
  373. +obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o
  374. +obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o
  375. +obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o
  376. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c
  377. --- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  378. +++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-05-27 14:36:50.000000000 +0200
  379. @@ -0,0 +1,177 @@
  380. +/*
  381. + * AR71xx SoC routines
  382. + *
  383. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  384. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  385. + *
  386. + * This program is free software; you can redistribute it and/or modify it
  387. + * under the terms of the GNU General Public License version 2 as published
  388. + * by the Free Software Foundation.
  389. + */
  390. +
  391. +#include <linux/kernel.h>
  392. +#include <linux/module.h>
  393. +#include <linux/types.h>
  394. +#include <linux/mutex.h>
  395. +
  396. +#include <asm/mach-ar71xx/ar71xx.h>
  397. +
  398. +static DEFINE_MUTEX(ar71xx_flash_mutex);
  399. +
  400. +void __iomem *ar71xx_ddr_base;
  401. +EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
  402. +
  403. +void __iomem *ar71xx_pll_base;
  404. +EXPORT_SYMBOL_GPL(ar71xx_pll_base);
  405. +
  406. +void __iomem *ar71xx_reset_base;
  407. +EXPORT_SYMBOL_GPL(ar71xx_reset_base);
  408. +
  409. +void __iomem *ar71xx_gpio_base;
  410. +EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
  411. +
  412. +void __iomem *ar71xx_usb_ctrl_base;
  413. +EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
  414. +
  415. +void ar71xx_device_stop(u32 mask)
  416. +{
  417. + unsigned long flags;
  418. + u32 mask_inv;
  419. + u32 t;
  420. +
  421. + switch (ar71xx_soc) {
  422. + case AR71XX_SOC_AR7130:
  423. + case AR71XX_SOC_AR7141:
  424. + case AR71XX_SOC_AR7161:
  425. + local_irq_save(flags);
  426. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  427. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
  428. + local_irq_restore(flags);
  429. + break;
  430. +
  431. + case AR71XX_SOC_AR7240:
  432. + case AR71XX_SOC_AR7241:
  433. + case AR71XX_SOC_AR7242:
  434. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  435. + local_irq_save(flags);
  436. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  437. + t |= mask;
  438. + t &= ~mask_inv;
  439. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  440. + local_irq_restore(flags);
  441. + break;
  442. +
  443. + case AR71XX_SOC_AR9130:
  444. + case AR71XX_SOC_AR9132:
  445. + local_irq_save(flags);
  446. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  447. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
  448. + local_irq_restore(flags);
  449. + break;
  450. +
  451. + default:
  452. + BUG();
  453. + }
  454. +}
  455. +EXPORT_SYMBOL_GPL(ar71xx_device_stop);
  456. +
  457. +void ar71xx_device_start(u32 mask)
  458. +{
  459. + unsigned long flags;
  460. + u32 mask_inv;
  461. + u32 t;
  462. +
  463. + switch (ar71xx_soc) {
  464. + case AR71XX_SOC_AR7130:
  465. + case AR71XX_SOC_AR7141:
  466. + case AR71XX_SOC_AR7161:
  467. + local_irq_save(flags);
  468. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  469. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
  470. + local_irq_restore(flags);
  471. + break;
  472. +
  473. + case AR71XX_SOC_AR7240:
  474. + case AR71XX_SOC_AR7241:
  475. + case AR71XX_SOC_AR7242:
  476. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  477. + local_irq_save(flags);
  478. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  479. + t &= ~mask;
  480. + t |= mask_inv;
  481. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  482. + local_irq_restore(flags);
  483. + break;
  484. +
  485. + case AR71XX_SOC_AR9130:
  486. + case AR71XX_SOC_AR9132:
  487. + local_irq_save(flags);
  488. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  489. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
  490. + local_irq_restore(flags);
  491. + break;
  492. +
  493. + default:
  494. + BUG();
  495. + }
  496. +}
  497. +EXPORT_SYMBOL_GPL(ar71xx_device_start);
  498. +
  499. +int ar71xx_device_stopped(u32 mask)
  500. +{
  501. + unsigned long flags;
  502. + u32 t;
  503. +
  504. + switch (ar71xx_soc) {
  505. + case AR71XX_SOC_AR7130:
  506. + case AR71XX_SOC_AR7141:
  507. + case AR71XX_SOC_AR7161:
  508. + local_irq_save(flags);
  509. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  510. + local_irq_restore(flags);
  511. + break;
  512. +
  513. + case AR71XX_SOC_AR7240:
  514. + case AR71XX_SOC_AR7241:
  515. + case AR71XX_SOC_AR7242:
  516. + local_irq_save(flags);
  517. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  518. + local_irq_restore(flags);
  519. + break;
  520. +
  521. + case AR71XX_SOC_AR9130:
  522. + case AR71XX_SOC_AR9132:
  523. + local_irq_save(flags);
  524. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  525. + local_irq_restore(flags);
  526. + break;
  527. +
  528. + default:
  529. + BUG();
  530. + }
  531. +
  532. + return ((t & mask) == mask);
  533. +}
  534. +EXPORT_SYMBOL_GPL(ar71xx_device_stopped);
  535. +
  536. +void ar71xx_ddr_flush(u32 reg)
  537. +{
  538. + ar71xx_ddr_wr(reg, 1);
  539. + while ((ar71xx_ddr_rr(reg) & 0x1));
  540. +
  541. + ar71xx_ddr_wr(reg, 1);
  542. + while ((ar71xx_ddr_rr(reg) & 0x1));
  543. +}
  544. +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
  545. +
  546. +void ar71xx_flash_acquire(void)
  547. +{
  548. + mutex_lock(&ar71xx_flash_mutex);
  549. +}
  550. +EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
  551. +
  552. +void ar71xx_flash_release(void)
  553. +{
  554. + mutex_unlock(&ar71xx_flash_mutex);
  555. +}
  556. +EXPORT_SYMBOL_GPL(ar71xx_flash_release);
  557. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.c
  558. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.c 1970-01-01 01:00:00.000000000 +0100
  559. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.c 2011-05-27 14:36:50.000000000 +0200
  560. @@ -0,0 +1,70 @@
  561. +/*
  562. + * Atheros AP91 reference board ethernet initialization
  563. + *
  564. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  565. + *
  566. + * This program is free software; you can redistribute it and/or modify it
  567. + * under the terms of the GNU General Public License version 2 as published
  568. + * by the Free Software Foundation.
  569. + */
  570. +
  571. +#include "devices.h"
  572. +#include "dev-dsa.h"
  573. +#include "dev-ap91-eth.h"
  574. +
  575. +static struct dsa_chip_data ap91_dsa_chip = {
  576. + .port_names[0] = "cpu",
  577. + .port_names[1] = "lan1",
  578. + .port_names[2] = "lan2",
  579. + .port_names[3] = "lan3",
  580. + .port_names[4] = "lan4",
  581. +};
  582. +
  583. +static struct dsa_platform_data ap91_dsa_data = {
  584. + .nr_chips = 1,
  585. + .chip = &ap91_dsa_chip,
  586. +};
  587. +
  588. +static void ap91_eth_set_port_name(unsigned port, const char *name)
  589. +{
  590. + if (port < 1 || port > 5)
  591. + return;
  592. +
  593. + if (name)
  594. + ap91_dsa_chip.port_names[port] = (char *) name;
  595. +}
  596. +
  597. +void __init ap91_eth_init(u8 *mac_addr, const char *port_names[])
  598. +{
  599. + if (mac_addr)
  600. + ar71xx_set_mac_base(mac_addr);
  601. +
  602. + if (port_names) {
  603. + int i;
  604. +
  605. + for (i = 0; i < AP91_ETH_NUM_PORT_NAMES; i++)
  606. + ap91_eth_set_port_name(i + 1, port_names[i]);
  607. + }
  608. +
  609. + /* WAN port */
  610. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  611. + ar71xx_eth0_data.speed = SPEED_100;
  612. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  613. + ar71xx_eth0_data.fifo_cfg1 = 0x0fff0000;
  614. + ar71xx_eth0_data.fifo_cfg2 = 0x00001fff;
  615. + ar71xx_eth0_data.fifo_cfg3 = 0x008001ff;
  616. +
  617. + /* LAN ports */
  618. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  619. + ar71xx_eth1_data.speed = SPEED_1000;
  620. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  621. + ar71xx_eth1_data.fifo_cfg1 = 0x0fff0000;
  622. + ar71xx_eth1_data.fifo_cfg2 = 0x00001fff;
  623. + ar71xx_eth1_data.fifo_cfg3 = 0x008001ff;
  624. +
  625. + ar71xx_add_device_mdio(0x0);
  626. + ar71xx_add_device_eth(1);
  627. + ar71xx_add_device_eth(0);
  628. +
  629. + ar71xx_add_device_dsa(1, &ap91_dsa_data);
  630. +}
  631. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.h
  632. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.h 1970-01-01 01:00:00.000000000 +0100
  633. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.h 2011-05-27 14:36:50.000000000 +0200
  634. @@ -0,0 +1,23 @@
  635. +/*
  636. + * Atheros AP91 reference board ethernet initialization
  637. + *
  638. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  639. + *
  640. + * This program is free software; you can redistribute it and/or modify it
  641. + * under the terms of the GNU General Public License version 2 as published
  642. + * by the Free Software Foundation.
  643. + */
  644. +
  645. +#ifndef _AR71XX_DEV_AP91_ETH_H
  646. +#define _AR71XX_DEV_AP91_ETH_H
  647. +
  648. +#define AP91_ETH_NUM_PORT_NAMES 4
  649. +
  650. +#if defined(CONFIG_AR71XX_DEV_AP91_ETH)
  651. +void ap91_eth_init(u8 *mac_addr, const char *port_names[]) __init;
  652. +#else
  653. +static inline void ap91_eth_init(u8 *mac_addr) { }
  654. +#endif
  655. +
  656. +#endif /* _AR71XX_DEV_AP91_ETH_H */
  657. +
  658. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c
  659. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100
  660. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-05-27 14:36:50.000000000 +0200
  661. @@ -0,0 +1,114 @@
  662. +/*
  663. + * Atheros AP91 reference board PCI initialization
  664. + *
  665. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  666. + *
  667. + * This program is free software; you can redistribute it and/or modify it
  668. + * under the terms of the GNU General Public License version 2 as published
  669. + * by the Free Software Foundation.
  670. + */
  671. +
  672. +#include <linux/pci.h>
  673. +#include <linux/ath9k_platform.h>
  674. +#include <linux/delay.h>
  675. +
  676. +#include <asm/mach-ar71xx/ar71xx.h>
  677. +#include <asm/mach-ar71xx/pci.h>
  678. +
  679. +#include "dev-ap91-pci.h"
  680. +
  681. +static struct ath9k_platform_data ap91_wmac_data;
  682. +static char ap91_wmac_mac[6];
  683. +static int ap91_pci_fixup_enabled;
  684. +
  685. +static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
  686. + {
  687. + .slot = 0,
  688. + .pin = 1,
  689. + .irq = AR71XX_PCI_IRQ_DEV0,
  690. + }
  691. +};
  692. +
  693. +static int ap91_pci_plat_dev_init(struct pci_dev *dev)
  694. +{
  695. + switch(PCI_SLOT(dev->devfn)) {
  696. + case 0:
  697. + dev->dev.platform_data = &ap91_wmac_data;
  698. + break;
  699. + }
  700. +
  701. + return 0;
  702. +}
  703. +
  704. +static void ap91_pci_fixup(struct pci_dev *dev)
  705. +{
  706. + void __iomem *mem;
  707. + u16 *cal_data;
  708. + u16 cmd;
  709. + u32 val;
  710. +
  711. + if (!ap91_pci_fixup_enabled)
  712. + return;
  713. +
  714. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  715. +
  716. + cal_data = ap91_wmac_data.eeprom_data;
  717. + if (*cal_data != 0xa55a) {
  718. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  719. + pci_name(dev));
  720. + return;
  721. + }
  722. +
  723. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  724. + if (!mem) {
  725. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  726. + pci_name(dev));
  727. + return;
  728. + }
  729. +
  730. + /* Setup the PCI device to allow access to the internal registers */
  731. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
  732. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  733. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  734. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  735. +
  736. + /* set pointer to first reg address */
  737. + cal_data += 3;
  738. + while (*cal_data != 0xffff) {
  739. + u32 reg;
  740. + reg = *cal_data++;
  741. + val = *cal_data++;
  742. + val |= (*cal_data++) << 16;
  743. +
  744. + __raw_writel(val, mem + reg);
  745. + udelay(100);
  746. + }
  747. +
  748. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  749. + dev->vendor = val & 0xffff;
  750. + dev->device = (val >> 16) & 0xffff;
  751. +
  752. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  753. + dev->revision = val & 0xff;
  754. + dev->class = val >> 8; /* upper 3 bytes */
  755. +
  756. + iounmap(mem);
  757. +}
  758. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup);
  759. +
  760. +void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
  761. +{
  762. + if (cal_data)
  763. + memcpy(ap91_wmac_data.eeprom_data, cal_data,
  764. + sizeof(ap91_wmac_data.eeprom_data));
  765. +
  766. + if (mac_addr) {
  767. + memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac));
  768. + ap91_wmac_data.macaddr = ap91_wmac_mac;
  769. + }
  770. +
  771. + ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
  772. + ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
  773. +
  774. + ap91_pci_fixup_enabled = 1;
  775. +}
  776. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h
  777. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100
  778. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-05-27 14:36:50.000000000 +0200
  779. @@ -0,0 +1,21 @@
  780. +/*
  781. + * Atheros AP91 reference board PCI initialization
  782. + *
  783. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  784. + *
  785. + * This program is free software; you can redistribute it and/or modify it
  786. + * under the terms of the GNU General Public License version 2 as published
  787. + * by the Free Software Foundation.
  788. + */
  789. +
  790. +#ifndef _AR71XX_DEV_AP91_PCI_H
  791. +#define _AR71XX_DEV_AP91_PCI_H
  792. +
  793. +#if defined(CONFIG_AR71XX_DEV_AP91_PCI)
  794. +void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init;
  795. +#else
  796. +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { }
  797. +#endif
  798. +
  799. +#endif /* _AR71XX_DEV_AP91_PCI_H */
  800. +
  801. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c
  802. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100
  803. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-05-27 14:36:51.000000000 +0200
  804. @@ -0,0 +1,159 @@
  805. +/*
  806. + * Atheros AP94 reference board PCI initialization
  807. + *
  808. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  809. + *
  810. + * This program is free software; you can redistribute it and/or modify it
  811. + * under the terms of the GNU General Public License version 2 as published
  812. + * by the Free Software Foundation.
  813. + */
  814. +
  815. +#include <linux/pci.h>
  816. +#include <linux/ath9k_platform.h>
  817. +#include <linux/delay.h>
  818. +
  819. +#include <asm/mach-ar71xx/ar71xx.h>
  820. +#include <asm/mach-ar71xx/pci.h>
  821. +
  822. +#include "dev-ap94-pci.h"
  823. +
  824. +static struct ath9k_platform_data ap94_wmac0_data;
  825. +static struct ath9k_platform_data ap94_wmac1_data;
  826. +static char ap94_wmac0_mac[6];
  827. +static char ap94_wmac1_mac[6];
  828. +static int ap94_pci_fixup_enabled;
  829. +
  830. +static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
  831. + {
  832. + .slot = 0,
  833. + .pin = 1,
  834. + .irq = AR71XX_PCI_IRQ_DEV0,
  835. + }, {
  836. + .slot = 1,
  837. + .pin = 1,
  838. + .irq = AR71XX_PCI_IRQ_DEV1,
  839. + }
  840. +};
  841. +
  842. +static int ap94_pci_plat_dev_init(struct pci_dev *dev)
  843. +{
  844. + switch(PCI_SLOT(dev->devfn)) {
  845. + case 17:
  846. + dev->dev.platform_data = &ap94_wmac0_data;
  847. + break;
  848. +
  849. + case 18:
  850. + dev->dev.platform_data = &ap94_wmac1_data;
  851. + break;
  852. + }
  853. +
  854. + return 0;
  855. +}
  856. +
  857. +static void ap94_pci_fixup(struct pci_dev *dev)
  858. +{
  859. + void __iomem *mem;
  860. + u16 *cal_data;
  861. + u16 cmd;
  862. + u32 bar0;
  863. + u32 val;
  864. +
  865. + if (!ap94_pci_fixup_enabled)
  866. + return;
  867. +
  868. + switch (PCI_SLOT(dev->devfn)) {
  869. + case 17:
  870. + cal_data = ap94_wmac0_data.eeprom_data;
  871. + break;
  872. + case 18:
  873. + cal_data = ap94_wmac1_data.eeprom_data;
  874. + break;
  875. + default:
  876. + return;
  877. + }
  878. +
  879. + if (*cal_data != 0xa55a) {
  880. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  881. + pci_name(dev));
  882. + return;
  883. + }
  884. +
  885. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  886. + if (!mem) {
  887. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  888. + pci_name(dev));
  889. + return;
  890. + }
  891. +
  892. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  893. +
  894. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  895. +
  896. + /* Setup the PCI device to allow access to the internal registers */
  897. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE);
  898. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  899. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  900. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  901. +
  902. + /* set pointer to first reg address */
  903. + cal_data += 3;
  904. + while (*cal_data != 0xffff) {
  905. + u32 reg;
  906. + reg = *cal_data++;
  907. + val = *cal_data++;
  908. + val |= (*cal_data++) << 16;
  909. +
  910. + __raw_writel(val, mem + reg);
  911. + udelay(100);
  912. + }
  913. +
  914. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  915. + dev->vendor = val & 0xffff;
  916. + dev->device = (val >> 16) & 0xffff;
  917. +
  918. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  919. + dev->revision = val & 0xff;
  920. + dev->class = val >> 8; /* upper 3 bytes */
  921. +
  922. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  923. + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
  924. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  925. +
  926. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
  927. +
  928. + iounmap(mem);
  929. +}
  930. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup);
  931. +
  932. +void __init ap94_pci_enable_quirk_wndr3700(void)
  933. +{
  934. + ap94_wmac0_data.quirk_wndr3700 = 1;
  935. + ap94_wmac1_data.quirk_wndr3700 = 1;
  936. +}
  937. +
  938. +void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  939. + u8 *cal_data1, u8 *mac_addr1)
  940. +{
  941. + if (cal_data0)
  942. + memcpy(ap94_wmac0_data.eeprom_data, cal_data0,
  943. + sizeof(ap94_wmac0_data.eeprom_data));
  944. +
  945. + if (cal_data1)
  946. + memcpy(ap94_wmac1_data.eeprom_data, cal_data1,
  947. + sizeof(ap94_wmac1_data.eeprom_data));
  948. +
  949. + if (mac_addr0) {
  950. + memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac));
  951. + ap94_wmac0_data.macaddr = ap94_wmac0_mac;
  952. + }
  953. +
  954. + if (mac_addr1) {
  955. + memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac));
  956. + ap94_wmac1_data.macaddr = ap94_wmac1_mac;
  957. + }
  958. +
  959. + ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
  960. + ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
  961. +
  962. + ap94_pci_fixup_enabled = 1;
  963. +}
  964. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h
  965. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100
  966. +++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-05-27 14:36:51.000000000 +0200
  967. @@ -0,0 +1,28 @@
  968. +/*
  969. + * Atheros AP94 reference board PCI initialization
  970. + *
  971. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  972. + *
  973. + * This program is free software; you can redistribute it and/or modify it
  974. + * under the terms of the GNU General Public License version 2 as published
  975. + * by the Free Software Foundation.
  976. + */
  977. +
  978. +#ifndef _AR71XX_DEV_AP94_PCI_H
  979. +#define _AR71XX_DEV_AP94_PCI_H
  980. +
  981. +#if defined(CONFIG_AR71XX_DEV_AP94_PCI)
  982. +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  983. + u8 *cal_data1, u8 *mac_addr1) __init;
  984. +
  985. +void ap94_pci_enable_quirk_wndr3700(void) __init;
  986. +
  987. +#else
  988. +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  989. + u8 *cal_data1, u8 *mac_addr1) {}
  990. +
  991. +static inline void ap94_pci_enable_quirk_wndr3700(void) {}
  992. +#endif
  993. +
  994. +#endif /* _AR71XX_DEV_AP94_PCI_H */
  995. +
  996. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.c
  997. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c 1970-01-01 01:00:00.000000000 +0100
  998. +++ linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.c 2011-05-27 14:36:51.000000000 +0200
  999. @@ -0,0 +1,68 @@
  1000. +/*
  1001. + * Atheros AR913x SoC built-in WMAC device support
  1002. + *
  1003. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1004. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1005. + *
  1006. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1007. + *
  1008. + * This program is free software; you can redistribute it and/or modify it
  1009. + * under the terms of the GNU General Public License version 2 as published
  1010. + * by the Free Software Foundation.
  1011. + */
  1012. +
  1013. +#include <linux/kernel.h>
  1014. +#include <linux/init.h>
  1015. +#include <linux/delay.h>
  1016. +#include <linux/etherdevice.h>
  1017. +#include <linux/platform_device.h>
  1018. +#include <linux/ath9k_platform.h>
  1019. +
  1020. +#include <asm/mach-ar71xx/ar71xx.h>
  1021. +
  1022. +#include "dev-ar913x-wmac.h"
  1023. +
  1024. +static struct ath9k_platform_data ar913x_wmac_data;
  1025. +static char ar913x_wmac_mac[6];
  1026. +
  1027. +static struct resource ar913x_wmac_resources[] = {
  1028. + {
  1029. + .start = AR91XX_WMAC_BASE,
  1030. + .end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
  1031. + .flags = IORESOURCE_MEM,
  1032. + }, {
  1033. + .start = AR71XX_CPU_IRQ_IP2,
  1034. + .end = AR71XX_CPU_IRQ_IP2,
  1035. + .flags = IORESOURCE_IRQ,
  1036. + },
  1037. +};
  1038. +
  1039. +static struct platform_device ar913x_wmac_device = {
  1040. + .name = "ath9k",
  1041. + .id = -1,
  1042. + .resource = ar913x_wmac_resources,
  1043. + .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
  1044. + .dev = {
  1045. + .platform_data = &ar913x_wmac_data,
  1046. + },
  1047. +};
  1048. +
  1049. +void __init ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr)
  1050. +{
  1051. + if (cal_data)
  1052. + memcpy(ar913x_wmac_data.eeprom_data, cal_data,
  1053. + sizeof(ar913x_wmac_data.eeprom_data));
  1054. +
  1055. + if (mac_addr) {
  1056. + memcpy(ar913x_wmac_mac, mac_addr, sizeof(ar913x_wmac_mac));
  1057. + ar913x_wmac_data.macaddr = ar913x_wmac_mac;
  1058. + }
  1059. +
  1060. + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
  1061. + mdelay(10);
  1062. +
  1063. + ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
  1064. + mdelay(10);
  1065. +
  1066. + platform_device_register(&ar913x_wmac_device);
  1067. +}
  1068. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.h
  1069. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.h 1970-01-01 01:00:00.000000000 +0100
  1070. +++ linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.h 2011-05-27 14:36:51.000000000 +0200
  1071. @@ -0,0 +1,19 @@
  1072. +/*
  1073. + * Atheros AR913x SoC built-in WMAC device support
  1074. + *
  1075. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1076. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1077. + *
  1078. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1079. + *
  1080. + * This program is free software; you can redistribute it and/or modify it
  1081. + * under the terms of the GNU General Public License version 2 as published
  1082. + * by the Free Software Foundation.
  1083. + */
  1084. +
  1085. +#ifndef _AR71XX_DEV_AR913X_WMAC_H
  1086. +#define _AR71XX_DEV_AR913X_WMAC_H
  1087. +
  1088. +void ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init;
  1089. +
  1090. +#endif /* _AR71XX_DEV_AR913X_WMAC_H */
  1091. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c
  1092. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100
  1093. +++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-05-27 14:36:51.000000000 +0200
  1094. @@ -0,0 +1,50 @@
  1095. +/*
  1096. + * Atheros AR71xx DSA switch device support
  1097. + *
  1098. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1099. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1100. + *
  1101. + * This program is free software; you can redistribute it and/or modify it
  1102. + * under the terms of the GNU General Public License version 2 as published
  1103. + * by the Free Software Foundation.
  1104. + */
  1105. +
  1106. +#include <linux/init.h>
  1107. +#include <linux/platform_device.h>
  1108. +
  1109. +#include <asm/mach-ar71xx/ar71xx.h>
  1110. +
  1111. +#include "devices.h"
  1112. +#include "dev-dsa.h"
  1113. +
  1114. +static struct platform_device ar71xx_dsa_switch_device = {
  1115. + .name = "dsa",
  1116. + .id = 0,
  1117. +};
  1118. +
  1119. +void __init ar71xx_add_device_dsa(unsigned int id,
  1120. + struct dsa_platform_data *d)
  1121. +{
  1122. + int i;
  1123. +
  1124. + switch (id) {
  1125. + case 0:
  1126. + d->netdev = &ar71xx_eth0_device.dev;
  1127. + break;
  1128. + case 1:
  1129. + d->netdev = &ar71xx_eth1_device.dev;
  1130. + break;
  1131. + default:
  1132. + printk(KERN_ERR
  1133. + "ar71xx: invalid ethernet id %d for DSA switch\n",
  1134. + id);
  1135. + return;
  1136. + }
  1137. +
  1138. + for (i = 0; i < d->nr_chips; i++)
  1139. + d->chip[i].mii_bus = &ar71xx_mdio_device.dev;
  1140. +
  1141. + ar71xx_dsa_switch_device.dev.platform_data = d;
  1142. +
  1143. + platform_device_register(&ar71xx_dsa_switch_device);
  1144. +}
  1145. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar71xx/dev-dsa.h
  1146. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100
  1147. +++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-05-27 14:36:51.000000000 +0200
  1148. @@ -0,0 +1,20 @@
  1149. +/*
  1150. + * Atheros AR71xx DSA switch device support
  1151. + *
  1152. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1153. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1154. + *
  1155. + * This program is free software; you can redistribute it and/or modify it
  1156. + * under the terms of the GNU General Public License version 2 as published
  1157. + * by the Free Software Foundation.
  1158. + */
  1159. +
  1160. +#ifndef _AR71XX_DEV_DSA_H
  1161. +#define _AR71XX_DEV_DSA_H
  1162. +
  1163. +#include <net/dsa.h>
  1164. +
  1165. +void ar71xx_add_device_dsa(unsigned int id,
  1166. + struct dsa_platform_data *d) __init;
  1167. +
  1168. +#endif /* _AR71XX_DEV_DSA_H */
  1169. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c
  1170. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100
  1171. +++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-05-27 14:36:51.000000000 +0200
  1172. @@ -0,0 +1,58 @@
  1173. +/*
  1174. + * Atheros AR71xx GPIO button support
  1175. + *
  1176. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1177. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1178. + *
  1179. + * This program is free software; you can redistribute it and/or modify it
  1180. + * under the terms of the GNU General Public License version 2 as published
  1181. + * by the Free Software Foundation.
  1182. + */
  1183. +
  1184. +#include "linux/init.h"
  1185. +#include <linux/platform_device.h>
  1186. +
  1187. +#include "dev-gpio-buttons.h"
  1188. +
  1189. +void __init ar71xx_add_device_gpio_buttons(int id,
  1190. + unsigned poll_interval,
  1191. + unsigned nbuttons,
  1192. + struct gpio_button *buttons)
  1193. +{
  1194. + struct platform_device *pdev;
  1195. + struct gpio_buttons_platform_data pdata;
  1196. + struct gpio_button *p;
  1197. + int err;
  1198. +
  1199. + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
  1200. + if (!p)
  1201. + return;
  1202. +
  1203. + memcpy(p, buttons, nbuttons * sizeof(*p));
  1204. +
  1205. + pdev = platform_device_alloc("gpio-buttons", id);
  1206. + if (!pdev)
  1207. + goto err_free_buttons;
  1208. +
  1209. + memset(&pdata, 0, sizeof(pdata));
  1210. + pdata.poll_interval = poll_interval;
  1211. + pdata.nbuttons = nbuttons;
  1212. + pdata.buttons = p;
  1213. +
  1214. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1215. + if (err)
  1216. + goto err_put_pdev;
  1217. +
  1218. +
  1219. + err = platform_device_add(pdev);
  1220. + if (err)
  1221. + goto err_put_pdev;
  1222. +
  1223. + return;
  1224. +
  1225. +err_put_pdev:
  1226. + platform_device_put(pdev);
  1227. +
  1228. +err_free_buttons:
  1229. + kfree(p);
  1230. +}
  1231. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h
  1232. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100
  1233. +++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-05-27 14:36:51.000000000 +0200
  1234. @@ -0,0 +1,25 @@
  1235. +/*
  1236. + * Atheros AR71xx GPIO button support
  1237. + *
  1238. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1239. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1240. + *
  1241. + * This program is free software; you can redistribute it and/or modify it
  1242. + * under the terms of the GNU General Public License version 2 as published
  1243. + * by the Free Software Foundation.
  1244. + */
  1245. +
  1246. +#ifndef _AR71XX_DEV_GPIO_BUTTONS_H
  1247. +#define _AR71XX_DEV_GPIO_BUTTONS_H
  1248. +
  1249. +#include <linux/input.h>
  1250. +#include <linux/gpio_buttons.h>
  1251. +
  1252. +#include <asm/mach-ar71xx/platform.h>
  1253. +
  1254. +void ar71xx_add_device_gpio_buttons(int id,
  1255. + unsigned poll_interval,
  1256. + unsigned nbuttons,
  1257. + struct gpio_button *buttons) __init;
  1258. +
  1259. +#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */
  1260. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c
  1261. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100
  1262. +++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-05-27 14:36:51.000000000 +0200
  1263. @@ -0,0 +1,57 @@
  1264. +/*
  1265. + * Atheros AR71xx GPIO LED device support
  1266. + *
  1267. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1268. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1269. + *
  1270. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1271. + *
  1272. + * This program is free software; you can redistribute it and/or modify it
  1273. + * under the terms of the GNU General Public License version 2 as published
  1274. + * by the Free Software Foundation.
  1275. + */
  1276. +
  1277. +#include <linux/init.h>
  1278. +#include <linux/platform_device.h>
  1279. +#include <linux/slab.h>
  1280. +
  1281. +#include "dev-leds-gpio.h"
  1282. +
  1283. +void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
  1284. + struct gpio_led *leds)
  1285. +{
  1286. + struct platform_device *pdev;
  1287. + struct gpio_led_platform_data pdata;
  1288. + struct gpio_led *p;
  1289. + int err;
  1290. +
  1291. + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
  1292. + if (!p)
  1293. + return;
  1294. +
  1295. + memcpy(p, leds, num_leds * sizeof(*p));
  1296. +
  1297. + pdev = platform_device_alloc("leds-gpio", id);
  1298. + if (!pdev)
  1299. + goto err_free_leds;
  1300. +
  1301. + memset(&pdata, 0, sizeof(pdata));
  1302. + pdata.num_leds = num_leds;
  1303. + pdata.leds = p;
  1304. +
  1305. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1306. + if (err)
  1307. + goto err_put_pdev;
  1308. +
  1309. + err = platform_device_add(pdev);
  1310. + if (err)
  1311. + goto err_put_pdev;
  1312. +
  1313. + return;
  1314. +
  1315. +err_put_pdev:
  1316. + platform_device_put(pdev);
  1317. +
  1318. +err_free_leds:
  1319. + kfree(p);
  1320. +}
  1321. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h
  1322. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100
  1323. +++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-05-27 14:36:51.000000000 +0200
  1324. @@ -0,0 +1,21 @@
  1325. +/*
  1326. + * Atheros AR71xx GPIO LED device support
  1327. + *
  1328. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1329. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1330. + *
  1331. + * This program is free software; you can redistribute it and/or modify it
  1332. + * under the terms of the GNU General Public License version 2 as published
  1333. + * by the Free Software Foundation.
  1334. + */
  1335. +
  1336. +#ifndef _AR71XX_DEV_LEDS_GPIO_H
  1337. +#define _AR71XX_DEV_LEDS_GPIO_H
  1338. +
  1339. +#include <linux/leds.h>
  1340. +
  1341. +void ar71xx_add_device_leds_gpio(int id,
  1342. + unsigned num_leds,
  1343. + struct gpio_led *leds) __init;
  1344. +
  1345. +#endif /* _AR71XX_DEV_LEDS_GPIO_H */
  1346. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c
  1347. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100
  1348. +++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-05-27 14:36:51.000000000 +0200
  1349. @@ -0,0 +1,30 @@
  1350. +/*
  1351. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1352. + *
  1353. + * This program is free software; you can redistribute it and/or modify it
  1354. + * under the terms of the GNU General Public License version 2 as published
  1355. + * by the Free Software Foundation.
  1356. + */
  1357. +
  1358. +#include <linux/init.h>
  1359. +#include <linux/spi/spi.h>
  1360. +#include <linux/spi/flash.h>
  1361. +
  1362. +#include "devices.h"
  1363. +#include "dev-m25p80.h"
  1364. +
  1365. +static struct spi_board_info ar71xx_spi_info[] = {
  1366. + {
  1367. + .bus_num = 0,
  1368. + .chip_select = 0,
  1369. + .max_speed_hz = 25000000,
  1370. + .modalias = "m25p80",
  1371. + }
  1372. +};
  1373. +
  1374. +void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata)
  1375. +{
  1376. + ar71xx_spi_info[0].platform_data = pdata;
  1377. + ar71xx_add_device_spi(NULL, ar71xx_spi_info,
  1378. + ARRAY_SIZE(ar71xx_spi_info));
  1379. +}
  1380. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h
  1381. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100
  1382. +++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-05-27 14:36:51.000000000 +0200
  1383. @@ -0,0 +1,16 @@
  1384. +/*
  1385. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1386. + *
  1387. + * This program is free software; you can redistribute it and/or modify it
  1388. + * under the terms of the GNU General Public License version 2 as published
  1389. + * by the Free Software Foundation.
  1390. + */
  1391. +
  1392. +#ifndef _AR71XX_DEV_M25P80_H
  1393. +#define _AR71XX_DEV_M25P80_H
  1394. +
  1395. +#include <linux/spi/flash.h>
  1396. +
  1397. +void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init;
  1398. +
  1399. +#endif /* _AR71XX_DEV_M25P80_H */
  1400. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c
  1401. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100
  1402. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-05-27 14:36:51.000000000 +0200
  1403. @@ -0,0 +1,40 @@
  1404. +/*
  1405. + * Atheros PB42 reference board PCI initialization
  1406. + *
  1407. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1408. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1409. + *
  1410. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1411. + *
  1412. + * This program is free software; you can redistribute it and/or modify it
  1413. + * under the terms of the GNU General Public License version 2 as published
  1414. + * by the Free Software Foundation.
  1415. + */
  1416. +
  1417. +#include <linux/pci.h>
  1418. +
  1419. +#include <asm/mach-ar71xx/ar71xx.h>
  1420. +#include <asm/mach-ar71xx/pci.h>
  1421. +
  1422. +#include "dev-pb42-pci.h"
  1423. +
  1424. +static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
  1425. + {
  1426. + .slot = 0,
  1427. + .pin = 1,
  1428. + .irq = AR71XX_PCI_IRQ_DEV0,
  1429. + }, {
  1430. + .slot = 1,
  1431. + .pin = 1,
  1432. + .irq = AR71XX_PCI_IRQ_DEV1,
  1433. + }, {
  1434. + .slot = 2,
  1435. + .pin = 1,
  1436. + .irq = AR71XX_PCI_IRQ_DEV2,
  1437. + }
  1438. +};
  1439. +
  1440. +void __init pb42_pci_init(void)
  1441. +{
  1442. + ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
  1443. +}
  1444. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h
  1445. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100
  1446. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-05-27 14:36:51.000000000 +0200
  1447. @@ -0,0 +1,21 @@
  1448. +/*
  1449. + * Atheros PB42 reference board PCI initialization
  1450. + *
  1451. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1452. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1453. + *
  1454. + * This program is free software; you can redistribute it and/or modify it
  1455. + * under the terms of the GNU General Public License version 2 as published
  1456. + * by the Free Software Foundation.
  1457. + */
  1458. +
  1459. +#ifndef _AR71XX_DEV_PB42_PCI_H
  1460. +#define _AR71XX_DEV_PB42_PCI_H
  1461. +
  1462. +#if defined(CONFIG_AR71XX_DEV_PB42_PCI)
  1463. +void pb42_pci_init(void) __init;
  1464. +#else
  1465. +static inline void pb42_pci_init(void) { }
  1466. +#endif
  1467. +
  1468. +#endif /* _AR71XX_DEV_PB42_PCI_H */
  1469. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c
  1470. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100
  1471. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-05-27 14:36:51.000000000 +0200
  1472. @@ -0,0 +1,33 @@
  1473. +/*
  1474. + * Atheros PB9x reference board PCI initialization
  1475. + *
  1476. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1477. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1478. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1479. + *
  1480. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1481. + *
  1482. + * This program is free software; you can redistribute it and/or modify it
  1483. + * under the terms of the GNU General Public License version 2 as published
  1484. + * by the Free Software Foundation.
  1485. + */
  1486. +
  1487. +#include <linux/pci.h>
  1488. +
  1489. +#include <asm/mach-ar71xx/ar71xx.h>
  1490. +#include <asm/mach-ar71xx/pci.h>
  1491. +
  1492. +#include "dev-pb9x-pci.h"
  1493. +
  1494. +static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = {
  1495. + {
  1496. + .slot = 0,
  1497. + .pin = 1,
  1498. + .irq = AR71XX_PCI_IRQ_DEV0,
  1499. + }
  1500. +};
  1501. +
  1502. +void __init pb9x_pci_init(void)
  1503. +{
  1504. + ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs);
  1505. +}
  1506. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h
  1507. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100
  1508. +++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-05-27 14:36:51.000000000 +0200
  1509. @@ -0,0 +1,22 @@
  1510. +/*
  1511. + * Atheros PB9x reference board PCI initialization
  1512. + *
  1513. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1514. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1515. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1516. + *
  1517. + * This program is free software; you can redistribute it and/or modify it
  1518. + * under the terms of the GNU General Public License version 2 as published
  1519. + * by the Free Software Foundation.
  1520. + */
  1521. +
  1522. +#ifndef _AR71XX_DEV_PB9X_PCI_H
  1523. +#define _AR71XX_DEV_PB9X_PCI_H
  1524. +
  1525. +#if defined(CONFIG_AR71XX_DEV_PB9X_PCI)
  1526. +void pb9x_pci_init(void) __init;
  1527. +#else
  1528. +static inline void pb9x_pci_init(void) { }
  1529. +#endif
  1530. +
  1531. +#endif /* _AR71XX_DEV_PB9X_PCI_H */
  1532. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c
  1533. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100
  1534. +++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-05-27 14:36:51.000000000 +0200
  1535. @@ -0,0 +1,181 @@
  1536. +/*
  1537. + * Atheros AR71xx USB host device support
  1538. + *
  1539. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1540. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1541. + *
  1542. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1543. + *
  1544. + * This program is free software; you can redistribute it and/or modify it
  1545. + * under the terms of the GNU General Public License version 2 as published
  1546. + * by the Free Software Foundation.
  1547. + */
  1548. +
  1549. +#include <linux/kernel.h>
  1550. +#include <linux/init.h>
  1551. +#include <linux/delay.h>
  1552. +#include <linux/dma-mapping.h>
  1553. +#include <linux/platform_device.h>
  1554. +
  1555. +#include <asm/mach-ar71xx/ar71xx.h>
  1556. +#include <asm/mach-ar71xx/platform.h>
  1557. +
  1558. +#include "dev-usb.h"
  1559. +
  1560. +/*
  1561. + * OHCI (USB full speed host controller)
  1562. + */
  1563. +static struct resource ar71xx_ohci_resources[] = {
  1564. + [0] = {
  1565. + .start = AR71XX_OHCI_BASE,
  1566. + .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
  1567. + .flags = IORESOURCE_MEM,
  1568. + },
  1569. + [1] = {
  1570. + .start = AR71XX_MISC_IRQ_OHCI,
  1571. + .end = AR71XX_MISC_IRQ_OHCI,
  1572. + .flags = IORESOURCE_IRQ,
  1573. + },
  1574. +};
  1575. +
  1576. +static struct resource ar7240_ohci_resources[] = {
  1577. + [0] = {
  1578. + .start = AR7240_OHCI_BASE,
  1579. + .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
  1580. + .flags = IORESOURCE_MEM,
  1581. + },
  1582. + [1] = {
  1583. + .start = AR71XX_CPU_IRQ_USB,
  1584. + .end = AR71XX_CPU_IRQ_USB,
  1585. + .flags = IORESOURCE_IRQ,
  1586. + },
  1587. +};
  1588. +
  1589. +static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
  1590. +static struct platform_device ar71xx_ohci_device = {
  1591. + .name = "ar71xx-ohci",
  1592. + .id = -1,
  1593. + .resource = ar71xx_ohci_resources,
  1594. + .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
  1595. + .dev = {
  1596. + .dma_mask = &ar71xx_ohci_dmamask,
  1597. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1598. + },
  1599. +};
  1600. +
  1601. +/*
  1602. + * EHCI (USB full speed host controller)
  1603. + */
  1604. +static struct resource ar71xx_ehci_resources[] = {
  1605. + [0] = {
  1606. + .start = AR71XX_EHCI_BASE,
  1607. + .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
  1608. + .flags = IORESOURCE_MEM,
  1609. + },
  1610. + [1] = {
  1611. + .start = AR71XX_CPU_IRQ_USB,
  1612. + .end = AR71XX_CPU_IRQ_USB,
  1613. + .flags = IORESOURCE_IRQ,
  1614. + },
  1615. +};
  1616. +
  1617. +static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
  1618. +static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
  1619. +
  1620. +static struct platform_device ar71xx_ehci_device = {
  1621. + .name = "ar71xx-ehci",
  1622. + .id = -1,
  1623. + .resource = ar71xx_ehci_resources,
  1624. + .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
  1625. + .dev = {
  1626. + .dma_mask = &ar71xx_ehci_dmamask,
  1627. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1628. + .platform_data = &ar71xx_ehci_data,
  1629. + },
  1630. +};
  1631. +
  1632. +#define AR71XX_USB_RESET_MASK \
  1633. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
  1634. + | RESET_MODULE_USB_OHCI_DLL)
  1635. +
  1636. +#define AR7240_USB_RESET_MASK \
  1637. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
  1638. +
  1639. +static void __init ar71xx_usb_setup(void)
  1640. +{
  1641. + ar71xx_device_stop(AR71XX_USB_RESET_MASK);
  1642. + mdelay(1000);
  1643. + ar71xx_device_start(AR71XX_USB_RESET_MASK);
  1644. +
  1645. + /* Turning on the Buff and Desc swap bits */
  1646. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
  1647. +
  1648. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1649. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
  1650. +
  1651. + mdelay(900);
  1652. +
  1653. + platform_device_register(&ar71xx_ohci_device);
  1654. + platform_device_register(&ar71xx_ehci_device);
  1655. +}
  1656. +
  1657. +static void __init ar7240_usb_setup(void)
  1658. +{
  1659. + ar71xx_device_stop(AR7240_USB_RESET_MASK);
  1660. + mdelay(1000);
  1661. + ar71xx_device_start(AR7240_USB_RESET_MASK);
  1662. +
  1663. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1664. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
  1665. +
  1666. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  1667. + ar71xx_ehci_data.is_ar91xx = 1;
  1668. + ar71xx_ehci_device.resource = ar7240_ohci_resources;
  1669. + ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1670. + platform_device_register(&ar71xx_ehci_device);
  1671. + } else {
  1672. + ar71xx_ohci_device.resource = ar7240_ohci_resources;
  1673. + ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1674. + platform_device_register(&ar71xx_ohci_device);
  1675. + }
  1676. +}
  1677. +
  1678. +static void __init ar91xx_usb_setup(void)
  1679. +{
  1680. + ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
  1681. + mdelay(10);
  1682. +
  1683. + ar71xx_device_start(RESET_MODULE_USB_HOST);
  1684. + mdelay(10);
  1685. +
  1686. + ar71xx_device_start(RESET_MODULE_USB_PHY);
  1687. + mdelay(10);
  1688. +
  1689. + ar71xx_ehci_data.is_ar91xx = 1;
  1690. + platform_device_register(&ar71xx_ehci_device);
  1691. +}
  1692. +
  1693. +void __init ar71xx_add_device_usb(void)
  1694. +{
  1695. + switch (ar71xx_soc) {
  1696. + case AR71XX_SOC_AR7240:
  1697. + case AR71XX_SOC_AR7241:
  1698. + case AR71XX_SOC_AR7242:
  1699. + ar7240_usb_setup();
  1700. + break;
  1701. +
  1702. + case AR71XX_SOC_AR7130:
  1703. + case AR71XX_SOC_AR7141:
  1704. + case AR71XX_SOC_AR7161:
  1705. + ar71xx_usb_setup();
  1706. + break;
  1707. +
  1708. + case AR71XX_SOC_AR9130:
  1709. + case AR71XX_SOC_AR9132:
  1710. + ar91xx_usb_setup();
  1711. + break;
  1712. +
  1713. + default:
  1714. + BUG();
  1715. + }
  1716. +}
  1717. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar71xx/dev-usb.h
  1718. --- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100
  1719. +++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-05-27 14:36:51.000000000 +0200
  1720. @@ -0,0 +1,17 @@
  1721. +/*
  1722. + * Atheros AR71xx USB host device support
  1723. + *
  1724. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1725. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1726. + *
  1727. + * This program is free software; you can redistribute it and/or modify it
  1728. + * under the terms of the GNU General Public License version 2 as published
  1729. + * by the Free Software Foundation.
  1730. + */
  1731. +
  1732. +#ifndef _AR71XX_DEV_USB_H
  1733. +#define _AR71XX_DEV_USB_H
  1734. +
  1735. +void ar71xx_add_device_usb(void) __init;
  1736. +
  1737. +#endif /* _AR71XX_DEV_USB_H */
  1738. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c
  1739. --- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100
  1740. +++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-05-27 14:36:51.000000000 +0200
  1741. @@ -0,0 +1,575 @@
  1742. +/*
  1743. + * Atheros AR71xx SoC platform devices
  1744. + *
  1745. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1746. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1747. + *
  1748. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1749. + *
  1750. + * This program is free software; you can redistribute it and/or modify it
  1751. + * under the terms of the GNU General Public License version 2 as published
  1752. + * by the Free Software Foundation.
  1753. + */
  1754. +
  1755. +#include <linux/kernel.h>
  1756. +#include <linux/init.h>
  1757. +#include <linux/delay.h>
  1758. +#include <linux/etherdevice.h>
  1759. +#include <linux/platform_device.h>
  1760. +#include <linux/serial_8250.h>
  1761. +
  1762. +#include <asm/mach-ar71xx/ar71xx.h>
  1763. +
  1764. +#include "devices.h"
  1765. +
  1766. +static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
  1767. +
  1768. +static struct resource ar71xx_uart_resources[] = {
  1769. + {
  1770. + .start = AR71XX_UART_BASE,
  1771. + .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
  1772. + .flags = IORESOURCE_MEM,
  1773. + },
  1774. +};
  1775. +
  1776. +#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
  1777. +static struct plat_serial8250_port ar71xx_uart_data[] = {
  1778. + {
  1779. + .mapbase = AR71XX_UART_BASE,
  1780. + .irq = AR71XX_MISC_IRQ_UART,
  1781. + .flags = AR71XX_UART_FLAGS,
  1782. + .iotype = UPIO_MEM32,
  1783. + .regshift = 2,
  1784. + }, {
  1785. + /* terminating entry */
  1786. + }
  1787. +};
  1788. +
  1789. +static struct platform_device ar71xx_uart_device = {
  1790. + .name = "serial8250",
  1791. + .id = PLAT8250_DEV_PLATFORM,
  1792. + .resource = ar71xx_uart_resources,
  1793. + .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
  1794. + .dev = {
  1795. + .platform_data = ar71xx_uart_data
  1796. + },
  1797. +};
  1798. +
  1799. +void __init ar71xx_add_device_uart(void)
  1800. +{
  1801. + ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
  1802. + platform_device_register(&ar71xx_uart_device);
  1803. +}
  1804. +
  1805. +static struct resource ar71xx_mdio_resources[] = {
  1806. + {
  1807. + .name = "mdio_base",
  1808. + .flags = IORESOURCE_MEM,
  1809. + .start = AR71XX_GE0_BASE,
  1810. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1811. + }
  1812. +};
  1813. +
  1814. +static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
  1815. +
  1816. +struct platform_device ar71xx_mdio_device = {
  1817. + .name = "ag71xx-mdio",
  1818. + .id = -1,
  1819. + .resource = ar71xx_mdio_resources,
  1820. + .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
  1821. + .dev = {
  1822. + .platform_data = &ar71xx_mdio_data,
  1823. + },
  1824. +};
  1825. +
  1826. +void __init ar71xx_add_device_mdio(u32 phy_mask)
  1827. +{
  1828. + switch (ar71xx_soc) {
  1829. + case AR71XX_SOC_AR7240:
  1830. + case AR71XX_SOC_AR7241:
  1831. + case AR71XX_SOC_AR7242:
  1832. + ar71xx_mdio_data.is_ar7240 = 1;
  1833. + break;
  1834. + default:
  1835. + break;
  1836. + }
  1837. +
  1838. + ar71xx_mdio_data.phy_mask = phy_mask;
  1839. +
  1840. + platform_device_register(&ar71xx_mdio_device);
  1841. +}
  1842. +
  1843. +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
  1844. +{
  1845. + void __iomem *base;
  1846. + u32 t;
  1847. +
  1848. + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
  1849. +
  1850. + t = __raw_readl(base + cfg_reg);
  1851. + t &= ~(3 << shift);
  1852. + t |= (2 << shift);
  1853. + __raw_writel(t, base + cfg_reg);
  1854. + udelay(100);
  1855. +
  1856. + __raw_writel(pll_val, base + pll_reg);
  1857. +
  1858. + t |= (3 << shift);
  1859. + __raw_writel(t, base + cfg_reg);
  1860. + udelay(100);
  1861. +
  1862. + t &= ~(3 << shift);
  1863. + __raw_writel(t, base + cfg_reg);
  1864. + udelay(100);
  1865. +
  1866. + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
  1867. + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
  1868. +
  1869. + iounmap(base);
  1870. +}
  1871. +
  1872. +struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  1873. +struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  1874. +
  1875. +static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
  1876. +{
  1877. + struct ar71xx_eth_pll_data *pll_data;
  1878. + u32 pll_val;
  1879. +
  1880. + switch (mac) {
  1881. + case 0:
  1882. + pll_data = &ar71xx_eth0_pll_data;
  1883. + break;
  1884. + case 1:
  1885. + pll_data = &ar71xx_eth1_pll_data;
  1886. + break;
  1887. + default:
  1888. + BUG();
  1889. + }
  1890. +
  1891. + switch (speed) {
  1892. + case SPEED_10:
  1893. + pll_val = pll_data->pll_10;
  1894. + break;
  1895. + case SPEED_100:
  1896. + pll_val = pll_data->pll_100;
  1897. + break;
  1898. + case SPEED_1000:
  1899. + pll_val = pll_data->pll_1000;
  1900. + break;
  1901. + default:
  1902. + BUG();
  1903. + }
  1904. +
  1905. + return pll_val;
  1906. +}
  1907. +
  1908. +static void ar71xx_set_pll_ge0(int speed)
  1909. +{
  1910. + u32 val = ar71xx_get_eth_pll(0, speed);
  1911. +
  1912. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
  1913. + val, AR71XX_ETH0_PLL_SHIFT);
  1914. +}
  1915. +
  1916. +static void ar71xx_set_pll_ge1(int speed)
  1917. +{
  1918. + u32 val = ar71xx_get_eth_pll(1, speed);
  1919. +
  1920. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
  1921. + val, AR71XX_ETH1_PLL_SHIFT);
  1922. +}
  1923. +
  1924. +static void ar724x_set_pll_ge0(int speed)
  1925. +{
  1926. + /* TODO */
  1927. +}
  1928. +
  1929. +static void ar724x_set_pll_ge1(int speed)
  1930. +{
  1931. + /* TODO */
  1932. +}
  1933. +
  1934. +static void ar91xx_set_pll_ge0(int speed)
  1935. +{
  1936. + u32 val = ar71xx_get_eth_pll(0, speed);
  1937. +
  1938. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
  1939. + val, AR91XX_ETH0_PLL_SHIFT);
  1940. +}
  1941. +
  1942. +static void ar91xx_set_pll_ge1(int speed)
  1943. +{
  1944. + u32 val = ar71xx_get_eth_pll(1, speed);
  1945. +
  1946. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
  1947. + val, AR91XX_ETH1_PLL_SHIFT);
  1948. +}
  1949. +
  1950. +static void ar71xx_ddr_flush_ge0(void)
  1951. +{
  1952. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
  1953. +}
  1954. +
  1955. +static void ar71xx_ddr_flush_ge1(void)
  1956. +{
  1957. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
  1958. +}
  1959. +
  1960. +static void ar724x_ddr_flush_ge0(void)
  1961. +{
  1962. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
  1963. +}
  1964. +
  1965. +static void ar724x_ddr_flush_ge1(void)
  1966. +{
  1967. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
  1968. +}
  1969. +
  1970. +static void ar91xx_ddr_flush_ge0(void)
  1971. +{
  1972. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
  1973. +}
  1974. +
  1975. +static void ar91xx_ddr_flush_ge1(void)
  1976. +{
  1977. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
  1978. +}
  1979. +
  1980. +static struct resource ar71xx_eth0_resources[] = {
  1981. + {
  1982. + .name = "mac_base",
  1983. + .flags = IORESOURCE_MEM,
  1984. + .start = AR71XX_GE0_BASE,
  1985. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1986. + }, {
  1987. + .name = "mii_ctrl",
  1988. + .flags = IORESOURCE_MEM,
  1989. + .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
  1990. + .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
  1991. + }, {
  1992. + .name = "mac_irq",
  1993. + .flags = IORESOURCE_IRQ,
  1994. + .start = AR71XX_CPU_IRQ_GE0,
  1995. + .end = AR71XX_CPU_IRQ_GE0,
  1996. + },
  1997. +};
  1998. +
  1999. +struct ag71xx_platform_data ar71xx_eth0_data = {
  2000. + .reset_bit = RESET_MODULE_GE0_MAC,
  2001. +};
  2002. +
  2003. +struct platform_device ar71xx_eth0_device = {
  2004. + .name = "ag71xx",
  2005. + .id = 0,
  2006. + .resource = ar71xx_eth0_resources,
  2007. + .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
  2008. + .dev = {
  2009. + .platform_data = &ar71xx_eth0_data,
  2010. + },
  2011. +};
  2012. +
  2013. +static struct resource ar71xx_eth1_resources[] = {
  2014. + {
  2015. + .name = "mac_base",
  2016. + .flags = IORESOURCE_MEM,
  2017. + .start = AR71XX_GE1_BASE,
  2018. + .end = AR71XX_GE1_BASE + 0x200 - 1,
  2019. + }, {
  2020. + .name = "mii_ctrl",
  2021. + .flags = IORESOURCE_MEM,
  2022. + .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
  2023. + .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
  2024. + }, {
  2025. + .name = "mac_irq",
  2026. + .flags = IORESOURCE_IRQ,
  2027. + .start = AR71XX_CPU_IRQ_GE1,
  2028. + .end = AR71XX_CPU_IRQ_GE1,
  2029. + },
  2030. +};
  2031. +
  2032. +struct ag71xx_platform_data ar71xx_eth1_data = {
  2033. + .reset_bit = RESET_MODULE_GE1_MAC,
  2034. +};
  2035. +
  2036. +struct platform_device ar71xx_eth1_device = {
  2037. + .name = "ag71xx",
  2038. + .id = 1,
  2039. + .resource = ar71xx_eth1_resources,
  2040. + .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
  2041. + .dev = {
  2042. + .platform_data = &ar71xx_eth1_data,
  2043. + },
  2044. +};
  2045. +
  2046. +#define AR71XX_PLL_VAL_1000 0x00110000
  2047. +#define AR71XX_PLL_VAL_100 0x00001099
  2048. +#define AR71XX_PLL_VAL_10 0x00991099
  2049. +
  2050. +#define AR724X_PLL_VAL_1000 0x00110000
  2051. +#define AR724X_PLL_VAL_100 0x00001099
  2052. +#define AR724X_PLL_VAL_10 0x00991099
  2053. +
  2054. +#define AR91XX_PLL_VAL_1000 0x1a000000
  2055. +#define AR91XX_PLL_VAL_100 0x13000a44
  2056. +#define AR91XX_PLL_VAL_10 0x00441099
  2057. +
  2058. +static void __init ar71xx_init_eth_pll_data(unsigned int id)
  2059. +{
  2060. + struct ar71xx_eth_pll_data *pll_data;
  2061. + u32 pll_10, pll_100, pll_1000;
  2062. +
  2063. + switch (id) {
  2064. + case 0:
  2065. + pll_data = &ar71xx_eth0_pll_data;
  2066. + break;
  2067. + case 1:
  2068. + pll_data = &ar71xx_eth1_pll_data;
  2069. + break;
  2070. + default:
  2071. + BUG();
  2072. + }
  2073. +
  2074. + switch (ar71xx_soc) {
  2075. + case AR71XX_SOC_AR7130:
  2076. + case AR71XX_SOC_AR7141:
  2077. + case AR71XX_SOC_AR7161:
  2078. + pll_10 = AR71XX_PLL_VAL_10;
  2079. + pll_100 = AR71XX_PLL_VAL_100;
  2080. + pll_1000 = AR71XX_PLL_VAL_1000;
  2081. + break;
  2082. +
  2083. + case AR71XX_SOC_AR7240:
  2084. + case AR71XX_SOC_AR7241:
  2085. + case AR71XX_SOC_AR7242:
  2086. + pll_10 = AR724X_PLL_VAL_10;
  2087. + pll_100 = AR724X_PLL_VAL_100;
  2088. + pll_1000 = AR724X_PLL_VAL_1000;
  2089. + break;
  2090. +
  2091. + case AR71XX_SOC_AR9130:
  2092. + case AR71XX_SOC_AR9132:
  2093. + pll_10 = AR91XX_PLL_VAL_10;
  2094. + pll_100 = AR91XX_PLL_VAL_100;
  2095. + pll_1000 = AR91XX_PLL_VAL_1000;
  2096. + break;
  2097. + default:
  2098. + BUG();
  2099. + }
  2100. +
  2101. + if (!pll_data->pll_10)
  2102. + pll_data->pll_10 = pll_10;
  2103. +
  2104. + if (!pll_data->pll_100)
  2105. + pll_data->pll_100 = pll_100;
  2106. +
  2107. + if (!pll_data->pll_1000)
  2108. + pll_data->pll_1000 = pll_1000;
  2109. +}
  2110. +
  2111. +static int ar71xx_eth_instance __initdata;
  2112. +void __init ar71xx_add_device_eth(unsigned int id)
  2113. +{
  2114. + struct platform_device *pdev;
  2115. + struct ag71xx_platform_data *pdata;
  2116. +
  2117. + ar71xx_init_eth_pll_data(id);
  2118. +
  2119. + switch (id) {
  2120. + case 0:
  2121. + switch (ar71xx_eth0_data.phy_if_mode) {
  2122. + case PHY_INTERFACE_MODE_MII:
  2123. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
  2124. + break;
  2125. + case PHY_INTERFACE_MODE_GMII:
  2126. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
  2127. + break;
  2128. + case PHY_INTERFACE_MODE_RGMII:
  2129. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
  2130. + break;
  2131. + case PHY_INTERFACE_MODE_RMII:
  2132. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
  2133. + break;
  2134. + default:
  2135. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2136. + "for eth0\n");
  2137. + return;
  2138. + }
  2139. + pdev = &ar71xx_eth0_device;
  2140. + break;
  2141. + case 1:
  2142. + switch (ar71xx_eth1_data.phy_if_mode) {
  2143. + case PHY_INTERFACE_MODE_RMII:
  2144. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
  2145. + break;
  2146. + case PHY_INTERFACE_MODE_RGMII:
  2147. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
  2148. + break;
  2149. + default:
  2150. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2151. + "for eth1\n");
  2152. + return;
  2153. + }
  2154. + pdev = &ar71xx_eth1_device;
  2155. + break;
  2156. + default:
  2157. + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
  2158. + return;
  2159. + }
  2160. +
  2161. + pdata = pdev->dev.platform_data;
  2162. +
  2163. + switch (ar71xx_soc) {
  2164. + case AR71XX_SOC_AR7130:
  2165. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2166. + : ar71xx_ddr_flush_ge0;
  2167. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2168. + : ar71xx_set_pll_ge0;
  2169. + break;
  2170. +
  2171. + case AR71XX_SOC_AR7141:
  2172. + case AR71XX_SOC_AR7161:
  2173. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2174. + : ar71xx_ddr_flush_ge0;
  2175. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2176. + : ar71xx_set_pll_ge0;
  2177. + pdata->has_gbit = 1;
  2178. + break;
  2179. +
  2180. + case AR71XX_SOC_AR7241:
  2181. + case AR71XX_SOC_AR7242:
  2182. + ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
  2183. + ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
  2184. + /* fall through */
  2185. + case AR71XX_SOC_AR7240:
  2186. + pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
  2187. + : ar724x_ddr_flush_ge0;
  2188. + pdata->set_pll = id ? ar724x_set_pll_ge1
  2189. + : ar724x_set_pll_ge0;
  2190. + pdata->is_ar724x = 1;
  2191. + break;
  2192. +
  2193. + case AR71XX_SOC_AR9130:
  2194. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2195. + : ar91xx_ddr_flush_ge0;
  2196. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2197. + : ar91xx_set_pll_ge0;
  2198. + pdata->is_ar91xx = 1;
  2199. + break;
  2200. +
  2201. + case AR71XX_SOC_AR9132:
  2202. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2203. + : ar91xx_ddr_flush_ge0;
  2204. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2205. + : ar91xx_set_pll_ge0;
  2206. + pdata->is_ar91xx = 1;
  2207. + pdata->has_gbit = 1;
  2208. + break;
  2209. +
  2210. + default:
  2211. + BUG();
  2212. + }
  2213. +
  2214. + switch (pdata->phy_if_mode) {
  2215. + case PHY_INTERFACE_MODE_GMII:
  2216. + case PHY_INTERFACE_MODE_RGMII:
  2217. + if (!pdata->has_gbit) {
  2218. + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
  2219. + id);
  2220. + return;
  2221. + }
  2222. + /* fallthrough */
  2223. + default:
  2224. + break;
  2225. + }
  2226. +
  2227. + if (is_valid_ether_addr(ar71xx_mac_base)) {
  2228. + memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
  2229. + pdata->mac_addr[5] += ar71xx_eth_instance;
  2230. + } else {
  2231. + random_ether_addr(pdata->mac_addr);
  2232. + printk(KERN_DEBUG
  2233. + "ar71xx: using random MAC address for eth%d\n",
  2234. + ar71xx_eth_instance);
  2235. + }
  2236. +
  2237. + if (pdata->mii_bus_dev == NULL)
  2238. + pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
  2239. +
  2240. + /* Reset the device */
  2241. + ar71xx_device_stop(pdata->reset_bit);
  2242. + mdelay(100);
  2243. +
  2244. + ar71xx_device_start(pdata->reset_bit);
  2245. + mdelay(100);
  2246. +
  2247. + platform_device_register(pdev);
  2248. + ar71xx_eth_instance++;
  2249. +}
  2250. +
  2251. +static struct resource ar71xx_spi_resources[] = {
  2252. + [0] = {
  2253. + .start = AR71XX_SPI_BASE,
  2254. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  2255. + .flags = IORESOURCE_MEM,
  2256. + },
  2257. +};
  2258. +
  2259. +static struct platform_device ar71xx_spi_device = {
  2260. + .name = "ar71xx-spi",
  2261. + .id = -1,
  2262. + .resource = ar71xx_spi_resources,
  2263. + .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
  2264. +};
  2265. +
  2266. +void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2267. + struct spi_board_info const *info,
  2268. + unsigned n)
  2269. +{
  2270. + spi_register_board_info(info, n);
  2271. + ar71xx_spi_device.dev.platform_data = pdata;
  2272. + platform_device_register(&ar71xx_spi_device);
  2273. +}
  2274. +
  2275. +void __init ar71xx_add_device_wdt(void)
  2276. +{
  2277. + platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
  2278. +}
  2279. +
  2280. +void __init ar71xx_set_mac_base(unsigned char *mac)
  2281. +{
  2282. + memcpy(ar71xx_mac_base, mac, ETH_ALEN);
  2283. +}
  2284. +
  2285. +void __init ar71xx_parse_mac_addr(char *mac_str)
  2286. +{
  2287. + u8 tmp[ETH_ALEN];
  2288. + int t;
  2289. +
  2290. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  2291. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2292. +
  2293. + if (t != ETH_ALEN)
  2294. + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
  2295. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2296. +
  2297. + if (t == ETH_ALEN)
  2298. + ar71xx_set_mac_base(tmp);
  2299. + else
  2300. + printk(KERN_DEBUG "ar71xx: failed to parse mac address "
  2301. + "\"%s\"\n", mac_str);
  2302. +}
  2303. +
  2304. +static int __init ar71xx_ethaddr_setup(char *str)
  2305. +{
  2306. + ar71xx_parse_mac_addr(str);
  2307. + return 1;
  2308. +}
  2309. +__setup("ethaddr=", ar71xx_ethaddr_setup);
  2310. +
  2311. +static int __init ar71xx_kmac_setup(char *str)
  2312. +{
  2313. + ar71xx_parse_mac_addr(str);
  2314. + return 1;
  2315. +}
  2316. +__setup("kmac=", ar71xx_kmac_setup);
  2317. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h
  2318. --- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100
  2319. +++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-05-27 14:36:51.000000000 +0200
  2320. @@ -0,0 +1,48 @@
  2321. +/*
  2322. + * Atheros AR71xx SoC device definitions
  2323. + *
  2324. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2325. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2326. + *
  2327. + * This program is free software; you can redistribute it and/or modify it
  2328. + * under the terms of the GNU General Public License version 2 as published
  2329. + * by the Free Software Foundation.
  2330. + */
  2331. +
  2332. +#ifndef __AR71XX_DEVICES_H
  2333. +#define __AR71XX_DEVICES_H
  2334. +
  2335. +#include <asm/mach-ar71xx/platform.h>
  2336. +
  2337. +struct platform_device;
  2338. +
  2339. +void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2340. + struct spi_board_info const *info,
  2341. + unsigned n) __init;
  2342. +
  2343. +void ar71xx_set_mac_base(unsigned char *mac) __init;
  2344. +void ar71xx_parse_mac_addr(char *mac_str) __init;
  2345. +
  2346. +struct ar71xx_eth_pll_data {
  2347. + u32 pll_10;
  2348. + u32 pll_100;
  2349. + u32 pll_1000;
  2350. +};
  2351. +
  2352. +extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  2353. +extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  2354. +
  2355. +extern struct ag71xx_platform_data ar71xx_eth0_data;
  2356. +extern struct ag71xx_platform_data ar71xx_eth1_data;
  2357. +extern struct platform_device ar71xx_eth0_device;
  2358. +extern struct platform_device ar71xx_eth1_device;
  2359. +void ar71xx_add_device_eth(unsigned int id) __init;
  2360. +
  2361. +extern struct platform_device ar71xx_mdio_device;
  2362. +void ar71xx_add_device_mdio(u32 phy_mask) __init;
  2363. +
  2364. +void ar71xx_add_device_uart(void) __init;
  2365. +
  2366. +void ar71xx_add_device_wdt(void) __init;
  2367. +
  2368. +#endif /* __AR71XX_DEVICES_H */
  2369. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c
  2370. --- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100
  2371. +++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-05-27 14:36:51.000000000 +0200
  2372. @@ -0,0 +1,30 @@
  2373. +/*
  2374. + * Atheros AR71xx SoC early printk support
  2375. + *
  2376. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2377. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2378. + *
  2379. + * This program is free software; you can redistribute it and/or modify it
  2380. + * under the terms of the GNU General Public License version 2 as published
  2381. + * by the Free Software Foundation.
  2382. + */
  2383. +
  2384. +#include <linux/io.h>
  2385. +#include <linux/serial_reg.h>
  2386. +#include <asm/addrspace.h>
  2387. +
  2388. +#include <asm/mach-ar71xx/ar71xx.h>
  2389. +
  2390. +#define UART_READ(r) \
  2391. + __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r)))
  2392. +
  2393. +#define UART_WRITE(r, v) \
  2394. + __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r)))
  2395. +
  2396. +void prom_putchar(unsigned char ch)
  2397. +{
  2398. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2399. + UART_WRITE(UART_TX, ch);
  2400. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2401. +}
  2402. +
  2403. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c
  2404. --- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
  2405. +++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-05-27 14:36:51.000000000 +0200
  2406. @@ -0,0 +1,182 @@
  2407. +/*
  2408. + * Atheros AR71xx SoC GPIO API support
  2409. + *
  2410. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2411. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2412. + *
  2413. + * This program is free software; you can redistribute it and/or modify it
  2414. + * under the terms of the GNU General Public License version 2 as published
  2415. + * by the Free Software Foundation.
  2416. + */
  2417. +
  2418. +#include <linux/kernel.h>
  2419. +#include <linux/init.h>
  2420. +#include <linux/module.h>
  2421. +#include <linux/types.h>
  2422. +#include <linux/spinlock.h>
  2423. +#include <linux/io.h>
  2424. +#include <linux/ioport.h>
  2425. +#include <linux/gpio.h>
  2426. +
  2427. +#include <asm/mach-ar71xx/ar71xx.h>
  2428. +
  2429. +static DEFINE_SPINLOCK(ar71xx_gpio_lock);
  2430. +
  2431. +unsigned long ar71xx_gpio_count;
  2432. +EXPORT_SYMBOL(ar71xx_gpio_count);
  2433. +
  2434. +void __ar71xx_gpio_set_value(unsigned gpio, int value)
  2435. +{
  2436. + void __iomem *base = ar71xx_gpio_base;
  2437. +
  2438. + if (value)
  2439. + __raw_writel(1 << gpio, base + GPIO_REG_SET);
  2440. + else
  2441. + __raw_writel(1 << gpio, base + GPIO_REG_CLEAR);
  2442. +}
  2443. +EXPORT_SYMBOL(__ar71xx_gpio_set_value);
  2444. +
  2445. +int __ar71xx_gpio_get_value(unsigned gpio)
  2446. +{
  2447. + return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1;
  2448. +}
  2449. +EXPORT_SYMBOL(__ar71xx_gpio_get_value);
  2450. +
  2451. +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  2452. +{
  2453. + return __ar71xx_gpio_get_value(offset);
  2454. +}
  2455. +
  2456. +static void ar71xx_gpio_set_value(struct gpio_chip *chip,
  2457. + unsigned offset, int value)
  2458. +{
  2459. + __ar71xx_gpio_set_value(offset, value);
  2460. +}
  2461. +
  2462. +static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
  2463. + unsigned offset)
  2464. +{
  2465. + void __iomem *base = ar71xx_gpio_base;
  2466. + unsigned long flags;
  2467. +
  2468. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2469. +
  2470. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset),
  2471. + base + GPIO_REG_OE);
  2472. +
  2473. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2474. +
  2475. + return 0;
  2476. +}
  2477. +
  2478. +static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
  2479. + unsigned offset, int value)
  2480. +{
  2481. + void __iomem *base = ar71xx_gpio_base;
  2482. + unsigned long flags;
  2483. +
  2484. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2485. +
  2486. + if (value)
  2487. + __raw_writel(1 << offset, base + GPIO_REG_SET);
  2488. + else
  2489. + __raw_writel(1 << offset, base + GPIO_REG_CLEAR);
  2490. +
  2491. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset),
  2492. + base + GPIO_REG_OE);
  2493. +
  2494. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2495. +
  2496. + return 0;
  2497. +}
  2498. +
  2499. +static struct gpio_chip ar71xx_gpio_chip = {
  2500. + .label = "ar71xx",
  2501. + .get = ar71xx_gpio_get_value,
  2502. + .set = ar71xx_gpio_set_value,
  2503. + .direction_input = ar71xx_gpio_direction_input,
  2504. + .direction_output = ar71xx_gpio_direction_output,
  2505. + .base = 0,
  2506. + .ngpio = AR71XX_GPIO_COUNT,
  2507. +};
  2508. +
  2509. +void ar71xx_gpio_function_enable(u32 mask)
  2510. +{
  2511. + void __iomem *base = ar71xx_gpio_base;
  2512. + unsigned long flags;
  2513. +
  2514. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2515. +
  2516. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask,
  2517. + base + GPIO_REG_FUNC);
  2518. + /* flush write */
  2519. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2520. +
  2521. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2522. +}
  2523. +
  2524. +void ar71xx_gpio_function_disable(u32 mask)
  2525. +{
  2526. + void __iomem *base = ar71xx_gpio_base;
  2527. + unsigned long flags;
  2528. +
  2529. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2530. +
  2531. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask,
  2532. + base + GPIO_REG_FUNC);
  2533. + /* flush write */
  2534. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2535. +
  2536. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2537. +}
  2538. +
  2539. +void ar71xx_gpio_function_setup(u32 set, u32 clear)
  2540. +{
  2541. + void __iomem *base = ar71xx_gpio_base;
  2542. + unsigned long flags;
  2543. +
  2544. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2545. +
  2546. + __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set,
  2547. + base + GPIO_REG_FUNC);
  2548. + /* flush write */
  2549. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2550. +
  2551. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2552. +}
  2553. +EXPORT_SYMBOL(ar71xx_gpio_function_setup);
  2554. +
  2555. +void __init ar71xx_gpio_init(void)
  2556. +{
  2557. + int err;
  2558. +
  2559. + if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
  2560. + "AR71xx GPIO controller"))
  2561. + panic("cannot allocate AR71xx GPIO registers page");
  2562. +
  2563. + switch (ar71xx_soc) {
  2564. + case AR71XX_SOC_AR7130:
  2565. + case AR71XX_SOC_AR7141:
  2566. + case AR71XX_SOC_AR7161:
  2567. + ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
  2568. + break;
  2569. +
  2570. + case AR71XX_SOC_AR7240:
  2571. + case AR71XX_SOC_AR7241:
  2572. + case AR71XX_SOC_AR7242:
  2573. + ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT;
  2574. + break;
  2575. +
  2576. + case AR71XX_SOC_AR9130:
  2577. + case AR71XX_SOC_AR9132:
  2578. + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
  2579. + break;
  2580. +
  2581. + default:
  2582. + BUG();
  2583. + }
  2584. +
  2585. + err = gpiochip_add(&ar71xx_gpio_chip);
  2586. + if (err)
  2587. + panic("cannot add AR71xx GPIO chip, error=%d", err);
  2588. +}
  2589. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx/irq.c
  2590. --- linux-2.6.39.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100
  2591. +++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-06-01 13:50:58.000000000 +0200
  2592. @@ -0,0 +1,293 @@
  2593. +/*
  2594. + * Atheros AR71xx SoC specific interrupt handling
  2595. + *
  2596. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2597. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2598. + *
  2599. + * Parts of this file are based on Atheros' 2.6.15 BSP
  2600. + *
  2601. + * This program is free software; you can redistribute it and/or modify it
  2602. + * under the terms of the GNU General Public License version 2 as published
  2603. + * by the Free Software Foundation.
  2604. + */
  2605. +
  2606. +#include <linux/kernel.h>
  2607. +#include <linux/init.h>
  2608. +#include <linux/interrupt.h>
  2609. +#include <linux/irq.h>
  2610. +
  2611. +#include <asm/irq_cpu.h>
  2612. +#include <asm/mipsregs.h>
  2613. +
  2614. +#include <asm/mach-ar71xx/ar71xx.h>
  2615. +
  2616. +static int ip2_flush_reg;
  2617. +
  2618. +static void ar71xx_gpio_irq_dispatch(void)
  2619. +{
  2620. + void __iomem *base = ar71xx_gpio_base;
  2621. + u32 pending;
  2622. +
  2623. + pending = __raw_readl(base + GPIO_REG_INT_PENDING) &
  2624. + __raw_readl(base + GPIO_REG_INT_ENABLE);
  2625. +
  2626. + if (pending)
  2627. + do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
  2628. + else
  2629. + spurious_interrupt();
  2630. +}
  2631. +
  2632. +static void ar71xx_gpio_irq_unmask(struct irq_data *d)
  2633. +{
  2634. + void __iomem *base = ar71xx_gpio_base;
  2635. + u32 t;
  2636. +
  2637. + d->irq -= AR71XX_GPIO_IRQ_BASE;
  2638. +
  2639. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2640. + __raw_writel(t | (1 << d->irq), base + GPIO_REG_INT_ENABLE);
  2641. +
  2642. + /* flush write */
  2643. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2644. +}
  2645. +
  2646. +static void ar71xx_gpio_irq_mask(struct irq_data *d)
  2647. +{
  2648. + void __iomem *base = ar71xx_gpio_base;
  2649. + u32 t;
  2650. +
  2651. + d->irq -= AR71XX_GPIO_IRQ_BASE;
  2652. +
  2653. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2654. + __raw_writel(t & ~(1 << d->irq), base + GPIO_REG_INT_ENABLE);
  2655. +
  2656. + /* flush write */
  2657. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2658. +}
  2659. +
  2660. +#if 0
  2661. +static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
  2662. +{
  2663. + /* TODO: implement */
  2664. + return 0;
  2665. +}
  2666. +#else
  2667. +#define ar71xx_gpio_irq_set_type NULL
  2668. +#endif
  2669. +
  2670. +static struct irq_chip ar71xx_gpio_irq_chip = {
  2671. + .name = "AR71XX GPIO",
  2672. + .irq_unmask = ar71xx_gpio_irq_unmask,
  2673. + .irq_mask = ar71xx_gpio_irq_mask,
  2674. + .irq_mask_ack = ar71xx_gpio_irq_mask,
  2675. + .irq_set_type = ar71xx_gpio_irq_set_type,
  2676. +};
  2677. +
  2678. +static struct irqaction ar71xx_gpio_irqaction = {
  2679. + .handler = no_action,
  2680. + .name = "cascade [AR71XX GPIO]",
  2681. +};
  2682. +
  2683. +#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH)
  2684. +#define GPIO_INT_ALL 0xffff
  2685. +
  2686. +static void __init ar71xx_gpio_irq_init(void)
  2687. +{
  2688. + void __iomem *base = ar71xx_gpio_base;
  2689. + int i;
  2690. +
  2691. + __raw_writel(0, base + GPIO_REG_INT_ENABLE);
  2692. + __raw_writel(0, base + GPIO_REG_INT_PENDING);
  2693. +
  2694. + /* setup type of all GPIO interrupts to level sensitive */
  2695. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE);
  2696. +
  2697. + /* setup polarity of all GPIO interrupts to active high */
  2698. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY);
  2699. +
  2700. + for (i = AR71XX_GPIO_IRQ_BASE;
  2701. + i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) {
  2702. + irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip,
  2703. + handle_level_irq);
  2704. + }
  2705. +
  2706. + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
  2707. +}
  2708. +
  2709. +static void ar71xx_misc_irq_dispatch(void)
  2710. +{
  2711. + u32 pending;
  2712. +
  2713. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
  2714. + & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
  2715. +
  2716. + if (pending & MISC_INT_UART)
  2717. + do_IRQ(AR71XX_MISC_IRQ_UART);
  2718. +
  2719. + else if (pending & MISC_INT_DMA)
  2720. + do_IRQ(AR71XX_MISC_IRQ_DMA);
  2721. +
  2722. + else if (pending & MISC_INT_PERFC)
  2723. + do_IRQ(AR71XX_MISC_IRQ_PERFC);
  2724. +
  2725. + else if (pending & MISC_INT_TIMER)
  2726. + do_IRQ(AR71XX_MISC_IRQ_TIMER);
  2727. +
  2728. + else if (pending & MISC_INT_OHCI)
  2729. + do_IRQ(AR71XX_MISC_IRQ_OHCI);
  2730. +
  2731. + else if (pending & MISC_INT_ERROR)
  2732. + do_IRQ(AR71XX_MISC_IRQ_ERROR);
  2733. +
  2734. + else if (pending & MISC_INT_GPIO)
  2735. + ar71xx_gpio_irq_dispatch();
  2736. +
  2737. + else if (pending & MISC_INT_WDOG)
  2738. + do_IRQ(AR71XX_MISC_IRQ_WDOG);
  2739. +
  2740. + else
  2741. + spurious_interrupt();
  2742. +}
  2743. +
  2744. +static void ar71xx_misc_irq_unmask(struct irq_data *d)
  2745. +{
  2746. + void __iomem *base = ar71xx_reset_base;
  2747. + u32 t;
  2748. +
  2749. + d->irq -= AR71XX_MISC_IRQ_BASE;
  2750. +
  2751. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2752. + __raw_writel(t | (1 << d->irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2753. +
  2754. + /* flush write */
  2755. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2756. +}
  2757. +
  2758. +static void ar71xx_misc_irq_mask(struct irq_data *d)
  2759. +{
  2760. + void __iomem *base = ar71xx_reset_base;
  2761. + u32 t;
  2762. +
  2763. + d->irq -= AR71XX_MISC_IRQ_BASE;
  2764. +
  2765. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2766. + __raw_writel(t & ~(1 << d->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 ar724x_misc_irq_ack(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_STATUS);
  2780. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2781. +
  2782. + /* flush write */
  2783. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2784. +}
  2785. +
  2786. +static struct irq_chip ar71xx_misc_irq_chip = {
  2787. + .name = "AR71XX MISC",
  2788. + .irq_unmask = ar71xx_misc_irq_unmask,
  2789. + .irq_mask = ar71xx_misc_irq_mask,
  2790. +};
  2791. +
  2792. +static struct irqaction ar71xx_misc_irqaction = {
  2793. + .handler = no_action,
  2794. + .name = "cascade [AR71XX MISC]",
  2795. +};
  2796. +
  2797. +static void __init ar71xx_misc_irq_init(void)
  2798. +{
  2799. + void __iomem *base = ar71xx_reset_base;
  2800. + int i;
  2801. +
  2802. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2803. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2804. +
  2805. + switch (ar71xx_soc) {
  2806. + case AR71XX_SOC_AR7240:
  2807. + case AR71XX_SOC_AR7241:
  2808. + case AR71XX_SOC_AR7242:
  2809. + ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
  2810. + break;
  2811. + default:
  2812. + ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
  2813. + break;
  2814. + }
  2815. +
  2816. + for (i = AR71XX_MISC_IRQ_BASE;
  2817. + i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) {
  2818. + irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip,
  2819. + handle_level_irq);
  2820. + }
  2821. +
  2822. + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
  2823. +}
  2824. +
  2825. +asmlinkage void plat_irq_dispatch(void)
  2826. +{
  2827. + unsigned long pending;
  2828. +
  2829. + pending = read_c0_status() & read_c0_cause() & ST0_IM;
  2830. +
  2831. + if (pending & STATUSF_IP7)
  2832. + do_IRQ(AR71XX_CPU_IRQ_TIMER);
  2833. +
  2834. + else if (pending & STATUSF_IP2) {
  2835. + /*
  2836. + * This IRQ is meant for a PCI device. Drivers for PCI devices
  2837. + * typically allocate coherent DMA memory for the descriptor
  2838. + * ring, however the DMA controller may still have some
  2839. + * unsynchronized data in the FIFO.
  2840. + * Issue a flush here to ensure that the driver sees the update.
  2841. + */
  2842. + ar71xx_ddr_flush(ip2_flush_reg);
  2843. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  2844. + }
  2845. +
  2846. + else if (pending & STATUSF_IP4)
  2847. + do_IRQ(AR71XX_CPU_IRQ_GE0);
  2848. +
  2849. + else if (pending & STATUSF_IP5)
  2850. + do_IRQ(AR71XX_CPU_IRQ_GE1);
  2851. +
  2852. + else if (pending & STATUSF_IP3)
  2853. + do_IRQ(AR71XX_CPU_IRQ_USB);
  2854. +
  2855. + else if (pending & STATUSF_IP6)
  2856. + ar71xx_misc_irq_dispatch();
  2857. +
  2858. + else
  2859. + spurious_interrupt();
  2860. +}
  2861. +
  2862. +void __init arch_init_irq(void)
  2863. +{
  2864. + switch(ar71xx_soc) {
  2865. + case AR71XX_SOC_AR7240:
  2866. + case AR71XX_SOC_AR7241:
  2867. + case AR71XX_SOC_AR7242:
  2868. + ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
  2869. + break;
  2870. + case AR71XX_SOC_AR9130:
  2871. + case AR71XX_SOC_AR9132:
  2872. + ip2_flush_reg = AR91XX_DDR_REG_FLUSH_WMAC;
  2873. + break;
  2874. + default:
  2875. + ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
  2876. + break;
  2877. + }
  2878. + mips_cpu_irq_init();
  2879. +
  2880. + ar71xx_misc_irq_init();
  2881. +
  2882. + cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC;
  2883. +
  2884. + ar71xx_gpio_irq_init();
  2885. +}
  2886. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c
  2887. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100
  2888. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-05-27 14:36:51.000000000 +0200
  2889. @@ -0,0 +1,140 @@
  2890. +/*
  2891. + * Atheros AP81 board support
  2892. + *
  2893. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  2894. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  2895. + *
  2896. + * This program is free software; you can redistribute it and/or modify it
  2897. + * under the terms of the GNU General Public License version 2 as published
  2898. + * by the Free Software Foundation.
  2899. + */
  2900. +
  2901. +#include <linux/mtd/mtd.h>
  2902. +#include <linux/mtd/partitions.h>
  2903. +
  2904. +#include <asm/mach-ar71xx/ar71xx.h>
  2905. +
  2906. +#include "machtype.h"
  2907. +#include "devices.h"
  2908. +#include "dev-m25p80.h"
  2909. +#include "dev-ar913x-wmac.h"
  2910. +#include "dev-gpio-buttons.h"
  2911. +#include "dev-leds-gpio.h"
  2912. +#include "dev-usb.h"
  2913. +
  2914. +#define AP81_GPIO_LED_STATUS 1
  2915. +#define AP81_GPIO_LED_AOSS 3
  2916. +#define AP81_GPIO_LED_WLAN 6
  2917. +#define AP81_GPIO_LED_POWER 14
  2918. +
  2919. +#define AP81_GPIO_BTN_SW4 12
  2920. +#define AP81_GPIO_BTN_SW1 21
  2921. +
  2922. +#define AP81_BUTTONS_POLL_INTERVAL 20
  2923. +
  2924. +#ifdef CONFIG_MTD_PARTITIONS
  2925. +static struct mtd_partition ap81_partitions[] = {
  2926. + {
  2927. + .name = "u-boot",
  2928. + .offset = 0,
  2929. + .size = 0x040000,
  2930. + .mask_flags = MTD_WRITEABLE,
  2931. + } , {
  2932. + .name = "u-boot-env",
  2933. + .offset = 0x040000,
  2934. + .size = 0x010000,
  2935. + } , {
  2936. + .name = "rootfs",
  2937. + .offset = 0x050000,
  2938. + .size = 0x500000,
  2939. + } , {
  2940. + .name = "uImage",
  2941. + .offset = 0x550000,
  2942. + .size = 0x100000,
  2943. + } , {
  2944. + .name = "ART",
  2945. + .offset = 0x650000,
  2946. + .size = 0x1b0000,
  2947. + .mask_flags = MTD_WRITEABLE,
  2948. + }
  2949. +};
  2950. +#endif /* CONFIG_MTD_PARTITIONS */
  2951. +
  2952. +static struct flash_platform_data ap81_flash_data = {
  2953. +#ifdef CONFIG_MTD_PARTITIONS
  2954. + .parts = ap81_partitions,
  2955. + .nr_parts = ARRAY_SIZE(ap81_partitions),
  2956. +#endif
  2957. +};
  2958. +
  2959. +static struct gpio_led ap81_leds_gpio[] __initdata = {
  2960. + {
  2961. + .name = "ap81:green:status",
  2962. + .gpio = AP81_GPIO_LED_STATUS,
  2963. + .active_low = 1,
  2964. + }, {
  2965. + .name = "ap81:amber:aoss",
  2966. + .gpio = AP81_GPIO_LED_AOSS,
  2967. + .active_low = 1,
  2968. + }, {
  2969. + .name = "ap81:green:wlan",
  2970. + .gpio = AP81_GPIO_LED_WLAN,
  2971. + .active_low = 1,
  2972. + }, {
  2973. + .name = "ap81:green:power",
  2974. + .gpio = AP81_GPIO_LED_POWER,
  2975. + .active_low = 1,
  2976. + }
  2977. +};
  2978. +
  2979. +static struct gpio_button ap81_gpio_buttons[] __initdata = {
  2980. + {
  2981. + .desc = "sw1",
  2982. + .type = EV_KEY,
  2983. + .code = BTN_0,
  2984. + .threshold = 3,
  2985. + .gpio = AP81_GPIO_BTN_SW1,
  2986. + .active_low = 1,
  2987. + } , {
  2988. + .desc = "sw4",
  2989. + .type = EV_KEY,
  2990. + .code = BTN_1,
  2991. + .threshold = 3,
  2992. + .gpio = AP81_GPIO_BTN_SW4,
  2993. + .active_low = 1,
  2994. + }
  2995. +};
  2996. +
  2997. +static void __init ap81_setup(void)
  2998. +{
  2999. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3000. +
  3001. + ar71xx_set_mac_base(eeprom);
  3002. + ar71xx_add_device_mdio(0x0);
  3003. +
  3004. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3005. + ar71xx_eth0_data.speed = SPEED_100;
  3006. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3007. + ar71xx_eth0_data.has_ar8216 = 1;
  3008. +
  3009. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3010. + ar71xx_eth1_data.phy_mask = 0x10;
  3011. +
  3012. + ar71xx_add_device_eth(0);
  3013. + ar71xx_add_device_eth(1);
  3014. +
  3015. + ar71xx_add_device_usb();
  3016. +
  3017. + ar71xx_add_device_m25p80(&ap81_flash_data);
  3018. +
  3019. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
  3020. + ap81_leds_gpio);
  3021. +
  3022. + ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL,
  3023. + ARRAY_SIZE(ap81_gpio_buttons),
  3024. + ap81_gpio_buttons);
  3025. +
  3026. + ar913x_add_device_wmac(eeprom, NULL);
  3027. +}
  3028. +
  3029. +MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup);
  3030. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c
  3031. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100
  3032. +++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-05-27 14:36:51.000000000 +0200
  3033. @@ -0,0 +1,266 @@
  3034. +/*
  3035. + * Atheros AP83 board support
  3036. + *
  3037. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3038. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3039. + *
  3040. + * This program is free software; you can redistribute it and/or modify it
  3041. + * under the terms of the GNU General Public License version 2 as published
  3042. + * by the Free Software Foundation.
  3043. + */
  3044. +
  3045. +#include <linux/delay.h>
  3046. +#include <linux/platform_device.h>
  3047. +#include <linux/mtd/mtd.h>
  3048. +#include <linux/mtd/partitions.h>
  3049. +#include <linux/spi/spi.h>
  3050. +#include <linux/spi/spi_gpio.h>
  3051. +#include <linux/spi/vsc7385.h>
  3052. +
  3053. +#include <asm/mach-ar71xx/ar71xx.h>
  3054. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  3055. +
  3056. +#include "machtype.h"
  3057. +#include "devices.h"
  3058. +#include "dev-ar913x-wmac.h"
  3059. +#include "dev-gpio-buttons.h"
  3060. +#include "dev-leds-gpio.h"
  3061. +#include "dev-usb.h"
  3062. +
  3063. +#define AP83_GPIO_LED_WLAN 6
  3064. +#define AP83_GPIO_LED_POWER 14
  3065. +#define AP83_GPIO_LED_JUMPSTART 15
  3066. +#define AP83_GPIO_BTN_JUMPSTART 12
  3067. +#define AP83_GPIO_BTN_RESET 21
  3068. +
  3069. +#define AP83_050_GPIO_VSC7385_CS 1
  3070. +#define AP83_050_GPIO_VSC7385_MISO 3
  3071. +#define AP83_050_GPIO_VSC7385_MOSI 16
  3072. +#define AP83_050_GPIO_VSC7385_SCK 17
  3073. +
  3074. +#define AP83_BUTTONS_POLL_INTERVAL 20
  3075. +
  3076. +#ifdef CONFIG_MTD_PARTITIONS
  3077. +static struct mtd_partition ap83_flash_partitions[] = {
  3078. + {
  3079. + .name = "u-boot",
  3080. + .offset = 0,
  3081. + .size = 0x040000,
  3082. + .mask_flags = MTD_WRITEABLE,
  3083. + } , {
  3084. + .name = "u-boot-env",
  3085. + .offset = 0x040000,
  3086. + .size = 0x020000,
  3087. + .mask_flags = MTD_WRITEABLE,
  3088. + } , {
  3089. + .name = "kernel",
  3090. + .offset = 0x060000,
  3091. + .size = 0x140000,
  3092. + } , {
  3093. + .name = "rootfs",
  3094. + .offset = 0x1a0000,
  3095. + .size = 0x650000,
  3096. + } , {
  3097. + .name = "art",
  3098. + .offset = 0x7f0000,
  3099. + .size = 0x010000,
  3100. + .mask_flags = MTD_WRITEABLE,
  3101. + } , {
  3102. + .name = "firmware",
  3103. + .offset = 0x060000,
  3104. + .size = 0x790000,
  3105. + }
  3106. +};
  3107. +#endif /* CONFIG_MTD_PARTITIONS */
  3108. +
  3109. +static struct ar91xx_flash_platform_data ap83_flash_data = {
  3110. + .width = 2,
  3111. +#ifdef CONFIG_MTD_PARTITIONS
  3112. + .parts = ap83_flash_partitions,
  3113. + .nr_parts = ARRAY_SIZE(ap83_flash_partitions),
  3114. +#endif
  3115. +};
  3116. +
  3117. +static struct resource ap83_flash_resources[] = {
  3118. + [0] = {
  3119. + .start = AR71XX_SPI_BASE,
  3120. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3121. + .flags = IORESOURCE_MEM,
  3122. + },
  3123. +};
  3124. +
  3125. +static struct platform_device ap83_flash_device = {
  3126. + .name = "ar91xx-flash",
  3127. + .id = -1,
  3128. + .resource = ap83_flash_resources,
  3129. + .num_resources = ARRAY_SIZE(ap83_flash_resources),
  3130. + .dev = {
  3131. + .platform_data = &ap83_flash_data,
  3132. + }
  3133. +};
  3134. +
  3135. +static struct gpio_led ap83_leds_gpio[] __initdata = {
  3136. + {
  3137. + .name = "ap83:green:jumpstart",
  3138. + .gpio = AP83_GPIO_LED_JUMPSTART,
  3139. + .active_low = 0,
  3140. + }, {
  3141. + .name = "ap83:green:power",
  3142. + .gpio = AP83_GPIO_LED_POWER,
  3143. + .active_low = 0,
  3144. + }, {
  3145. + .name = "ap83:green:wlan",
  3146. + .gpio = AP83_GPIO_LED_WLAN,
  3147. + .active_low = 0,
  3148. + },
  3149. +};
  3150. +
  3151. +static struct gpio_button ap83_gpio_buttons[] __initdata = {
  3152. + {
  3153. + .desc = "soft_reset",
  3154. + .type = EV_KEY,
  3155. + .code = KEY_RESTART,
  3156. + .threshold = 3,
  3157. + .gpio = AP83_GPIO_BTN_RESET,
  3158. + .active_low = 1,
  3159. + } , {
  3160. + .desc = "jumpstart",
  3161. + .type = EV_KEY,
  3162. + .code = KEY_WPS_BUTTON,
  3163. + .threshold = 3,
  3164. + .gpio = AP83_GPIO_BTN_JUMPSTART,
  3165. + .active_low = 1,
  3166. + }
  3167. +};
  3168. +
  3169. +static struct resource ap83_040_spi_resources[] = {
  3170. + [0] = {
  3171. + .start = AR71XX_SPI_BASE,
  3172. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3173. + .flags = IORESOURCE_MEM,
  3174. + },
  3175. +};
  3176. +
  3177. +static struct platform_device ap83_040_spi_device = {
  3178. + .name = "ap83-spi",
  3179. + .id = 0,
  3180. + .resource = ap83_040_spi_resources,
  3181. + .num_resources = ARRAY_SIZE(ap83_040_spi_resources),
  3182. +};
  3183. +
  3184. +static struct spi_gpio_platform_data ap83_050_spi_data = {
  3185. + .miso = AP83_050_GPIO_VSC7385_MISO,
  3186. + .mosi = AP83_050_GPIO_VSC7385_MOSI,
  3187. + .sck = AP83_050_GPIO_VSC7385_SCK,
  3188. + .num_chipselect = 1,
  3189. +};
  3190. +
  3191. +static struct platform_device ap83_050_spi_device = {
  3192. + .name = "spi_gpio",
  3193. + .id = 0,
  3194. + .dev = {
  3195. + .platform_data = &ap83_050_spi_data,
  3196. + }
  3197. +};
  3198. +
  3199. +static void ap83_vsc7385_reset(void)
  3200. +{
  3201. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  3202. + udelay(10);
  3203. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  3204. + mdelay(50);
  3205. +}
  3206. +
  3207. +static struct vsc7385_platform_data ap83_vsc7385_data = {
  3208. + .reset = ap83_vsc7385_reset,
  3209. + .ucode_name = "vsc7385_ucode_ap83.bin",
  3210. + .mac_cfg = {
  3211. + .tx_ipg = 6,
  3212. + .bit2 = 0,
  3213. + .clk_sel = 3,
  3214. + },
  3215. +};
  3216. +
  3217. +static struct spi_board_info ap83_spi_info[] = {
  3218. + {
  3219. + .bus_num = 0,
  3220. + .chip_select = 0,
  3221. + .max_speed_hz = 25000000,
  3222. + .modalias = "spi-vsc7385",
  3223. + .platform_data = &ap83_vsc7385_data,
  3224. + .controller_data = (void *) AP83_050_GPIO_VSC7385_CS,
  3225. + }
  3226. +};
  3227. +
  3228. +static void __init ap83_generic_setup(void)
  3229. +{
  3230. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3231. +
  3232. + ar71xx_set_mac_base(eeprom);
  3233. +
  3234. + ar71xx_add_device_mdio(0xfffffffe);
  3235. +
  3236. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3237. + ar71xx_eth0_data.phy_mask = 0x1;
  3238. +
  3239. + ar71xx_add_device_eth(0);
  3240. +
  3241. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3242. + ar71xx_eth1_data.speed = SPEED_1000;
  3243. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  3244. +
  3245. + ar71xx_eth1_pll_data.pll_1000 = 0x1f000000;
  3246. +
  3247. + ar71xx_add_device_eth(1);
  3248. +
  3249. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
  3250. + ap83_leds_gpio);
  3251. +
  3252. + ar71xx_add_device_gpio_buttons(-1, AP83_BUTTONS_POLL_INTERVAL,
  3253. + ARRAY_SIZE(ap83_gpio_buttons),
  3254. + ap83_gpio_buttons);
  3255. +
  3256. + ar71xx_add_device_usb();
  3257. +
  3258. + ar913x_add_device_wmac(eeprom, NULL);
  3259. +
  3260. + platform_device_register(&ap83_flash_device);
  3261. +
  3262. + spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info));
  3263. +}
  3264. +
  3265. +static void __init ap83_040_setup(void)
  3266. +{
  3267. + ap83_flash_data.is_shared=1;
  3268. + ap83_generic_setup();
  3269. + platform_device_register(&ap83_040_spi_device);
  3270. +}
  3271. +
  3272. +static void __init ap83_050_setup(void)
  3273. +{
  3274. + ap83_generic_setup();
  3275. + platform_device_register(&ap83_050_spi_device);
  3276. +}
  3277. +
  3278. +static void __init ap83_setup(void)
  3279. +{
  3280. + u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244);
  3281. + unsigned int board_version;
  3282. +
  3283. + board_version = (unsigned int)(board_id[0] - '0');
  3284. + board_version += ((unsigned int)(board_id[1] - '0')) * 10;
  3285. +
  3286. + switch (board_version) {
  3287. + case 40:
  3288. + ap83_040_setup();
  3289. + break;
  3290. + case 50:
  3291. + ap83_050_setup();
  3292. + break;
  3293. + default:
  3294. + printk(KERN_WARNING "AP83-%03u board is not yet supported\n",
  3295. + board_version);
  3296. + }
  3297. +}
  3298. +
  3299. +MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup);
  3300. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c
  3301. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100
  3302. +++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-05-27 14:36:51.000000000 +0200
  3303. @@ -0,0 +1,101 @@
  3304. +/*
  3305. + * AzureWave AW-NR580 board support
  3306. + *
  3307. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3308. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3309. + *
  3310. + * This program is free software; you can redistribute it and/or modify it
  3311. + * under the terms of the GNU General Public License version 2 as published
  3312. + * by the Free Software Foundation.
  3313. + */
  3314. +
  3315. +#include <linux/mtd/mtd.h>
  3316. +#include <linux/mtd/partitions.h>
  3317. +
  3318. +#include <asm/mips_machine.h>
  3319. +#include <asm/mach-ar71xx/ar71xx.h>
  3320. +
  3321. +#include "machtype.h"
  3322. +#include "devices.h"
  3323. +#include "dev-m25p80.h"
  3324. +#include "dev-gpio-buttons.h"
  3325. +#include "dev-pb42-pci.h"
  3326. +#include "dev-leds-gpio.h"
  3327. +
  3328. +#define AW_NR580_GPIO_LED_READY_RED 0
  3329. +#define AW_NR580_GPIO_LED_WLAN 1
  3330. +#define AW_NR580_GPIO_LED_READY_GREEN 2
  3331. +#define AW_NR580_GPIO_LED_WPS_GREEN 4
  3332. +#define AW_NR580_GPIO_LED_WPS_AMBER 5
  3333. +
  3334. +#define AW_NR580_GPIO_BTN_WPS 3
  3335. +#define AW_NR580_GPIO_BTN_RESET 11
  3336. +
  3337. +#define AW_NR580_BUTTONS_POLL_INTERVAL 20
  3338. +
  3339. +static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
  3340. + {
  3341. + .name = "aw-nr580:red:ready",
  3342. + .gpio = AW_NR580_GPIO_LED_READY_RED,
  3343. + .active_low = 0,
  3344. + }, {
  3345. + .name = "aw-nr580:green:ready",
  3346. + .gpio = AW_NR580_GPIO_LED_READY_GREEN,
  3347. + .active_low = 0,
  3348. + }, {
  3349. + .name = "aw-nr580:green:wps",
  3350. + .gpio = AW_NR580_GPIO_LED_WPS_GREEN,
  3351. + .active_low = 0,
  3352. + }, {
  3353. + .name = "aw-nr580:amber:wps",
  3354. + .gpio = AW_NR580_GPIO_LED_WPS_AMBER,
  3355. + .active_low = 0,
  3356. + }, {
  3357. + .name = "aw-nr580:green:wlan",
  3358. + .gpio = AW_NR580_GPIO_LED_WLAN,
  3359. + .active_low = 0,
  3360. + }
  3361. +};
  3362. +
  3363. +static struct gpio_button aw_nr580_gpio_buttons[] __initdata = {
  3364. + {
  3365. + .desc = "reset",
  3366. + .type = EV_KEY,
  3367. + .code = KEY_RESTART,
  3368. + .threshold = 3,
  3369. + .gpio = AW_NR580_GPIO_BTN_RESET,
  3370. + .active_low = 1,
  3371. + }, {
  3372. + .desc = "wps",
  3373. + .type = EV_KEY,
  3374. + .code = KEY_WPS_BUTTON,
  3375. + .threshold = 3,
  3376. + .gpio = AW_NR580_GPIO_BTN_WPS,
  3377. + .active_low = 1,
  3378. + }
  3379. +};
  3380. +
  3381. +static void __init aw_nr580_setup(void)
  3382. +{
  3383. + ar71xx_add_device_mdio(0x0);
  3384. +
  3385. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  3386. + ar71xx_eth0_data.speed = SPEED_100;
  3387. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3388. +
  3389. + ar71xx_add_device_eth(0);
  3390. +
  3391. + pb42_pci_init();
  3392. +
  3393. + ar71xx_add_device_m25p80(NULL);
  3394. +
  3395. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
  3396. + aw_nr580_leds_gpio);
  3397. +
  3398. + ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL,
  3399. + ARRAY_SIZE(aw_nr580_gpio_buttons),
  3400. + aw_nr580_gpio_buttons);
  3401. +}
  3402. +
  3403. +MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580",
  3404. + aw_nr580_setup);
  3405. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c
  3406. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100
  3407. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-05-27 14:36:51.000000000 +0200
  3408. @@ -0,0 +1,138 @@
  3409. +/*
  3410. + * D-Link DIR-600 rev. A1 board support
  3411. + *
  3412. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  3413. + *
  3414. + * This program is free software; you can redistribute it and/or modify it
  3415. + * under the terms of the GNU General Public License version 2 as published
  3416. + * by the Free Software Foundation.
  3417. + */
  3418. +
  3419. +#include <linux/mtd/mtd.h>
  3420. +#include <linux/mtd/partitions.h>
  3421. +
  3422. +#include <asm/mach-ar71xx/ar71xx.h>
  3423. +
  3424. +#include "machtype.h"
  3425. +#include "devices.h"
  3426. +#include "dev-m25p80.h"
  3427. +#include "dev-ap91-eth.h"
  3428. +#include "dev-ap91-pci.h"
  3429. +#include "dev-gpio-buttons.h"
  3430. +#include "dev-leds-gpio.h"
  3431. +#include "nvram.h"
  3432. +
  3433. +#define DIR_600_A1_GPIO_LED_WPS 0
  3434. +#define DIR_600_A1_GPIO_LED_POWER_AMBER 1
  3435. +#define DIR_600_A1_GPIO_LED_POWER_GREEN 6
  3436. +
  3437. +#define DIR_600_A1_GPIO_BTN_RESET 8
  3438. +#define DIR_600_A1_GPIO_BTN_WPS 12
  3439. +
  3440. +#define DIR_600_A1_BUTTONS_POLL_INTERVAL 20
  3441. +
  3442. +#define DIR_600_A1_NVRAM_ADDR 0x1f030000
  3443. +#define DIR_600_A1_NVRAM_SIZE 0x10000
  3444. +
  3445. +#ifdef CONFIG_MTD_PARTITIONS
  3446. +static struct mtd_partition dir_600_a1_partitions[] = {
  3447. + {
  3448. + .name = "u-boot",
  3449. + .offset = 0,
  3450. + .size = 0x030000,
  3451. + .mask_flags = MTD_WRITEABLE,
  3452. + }, {
  3453. + .name = "nvram",
  3454. + .offset = 0x030000,
  3455. + .size = 0x010000,
  3456. + }, {
  3457. + .name = "kernel",
  3458. + .offset = 0x040000,
  3459. + .size = 0x0e0000,
  3460. + }, {
  3461. + .name = "rootfs",
  3462. + .offset = 0x120000,
  3463. + .size = 0x2c0000,
  3464. + }, {
  3465. + .name = "mac",
  3466. + .offset = 0x3e0000,
  3467. + .size = 0x010000,
  3468. + .mask_flags = MTD_WRITEABLE,
  3469. + }, {
  3470. + .name = "art",
  3471. + .offset = 0x3f0000,
  3472. + .size = 0x010000,
  3473. + .mask_flags = MTD_WRITEABLE,
  3474. + }, {
  3475. + .name = "firmware",
  3476. + .offset = 0x040000,
  3477. + .size = 0x3a0000,
  3478. + }
  3479. +};
  3480. +#endif /* CONFIG_MTD_PARTITIONS */
  3481. +
  3482. +static struct flash_platform_data dir_600_a1_flash_data = {
  3483. +#ifdef CONFIG_MTD_PARTITIONS
  3484. + .parts = dir_600_a1_partitions,
  3485. + .nr_parts = ARRAY_SIZE(dir_600_a1_partitions),
  3486. +#endif
  3487. +};
  3488. +
  3489. +static struct gpio_led dir_600_a1_leds_gpio[] __initdata = {
  3490. + {
  3491. + .name = "dir-600-a1:green:power",
  3492. + .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN,
  3493. + }, {
  3494. + .name = "dir-600-a1:amber:power",
  3495. + .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER,
  3496. + }, {
  3497. + .name = "dir-600-a1:blue:wps",
  3498. + .gpio = DIR_600_A1_GPIO_LED_WPS,
  3499. + .active_low = 1,
  3500. + }
  3501. +};
  3502. +
  3503. +static struct gpio_button dir_600_a1_gpio_buttons[] __initdata = {
  3504. + {
  3505. + .desc = "reset",
  3506. + .type = EV_KEY,
  3507. + .code = KEY_RESTART,
  3508. + .threshold = 3,
  3509. + .gpio = DIR_600_A1_GPIO_BTN_RESET,
  3510. + .active_low = 1,
  3511. + }, {
  3512. + .desc = "wps",
  3513. + .type = EV_KEY,
  3514. + .code = KEY_WPS_BUTTON,
  3515. + .threshold = 3,
  3516. + .gpio = DIR_600_A1_GPIO_BTN_WPS,
  3517. + .active_low = 1,
  3518. + }
  3519. +};
  3520. +
  3521. +static void __init dir_600_a1_setup(void)
  3522. +{
  3523. + const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR);
  3524. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  3525. + u8 mac_buff[6];
  3526. + u8 *mac = NULL;
  3527. +
  3528. + if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE,
  3529. + "lan_mac=", mac_buff) == 0)
  3530. + mac = mac_buff;
  3531. +
  3532. + ar71xx_add_device_m25p80(&dir_600_a1_flash_data);
  3533. +
  3534. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio),
  3535. + dir_600_a1_leds_gpio);
  3536. +
  3537. + ar71xx_add_device_gpio_buttons(-1, DIR_600_A1_BUTTONS_POLL_INTERVAL,
  3538. + ARRAY_SIZE(dir_600_a1_gpio_buttons),
  3539. + dir_600_a1_gpio_buttons);
  3540. +
  3541. + ap91_eth_init(mac, NULL);
  3542. + ap91_pci_init(ee, mac);
  3543. +}
  3544. +
  3545. +MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1",
  3546. + dir_600_a1_setup);
  3547. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c
  3548. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100
  3549. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-05-27 14:36:51.000000000 +0200
  3550. @@ -0,0 +1,173 @@
  3551. +/*
  3552. + * D-Link DIR-615 rev C1 board support
  3553. + *
  3554. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3555. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3556. + *
  3557. + * This program is free software; you can redistribute it and/or modify it
  3558. + * under the terms of the GNU General Public License version 2 as published
  3559. + * by the Free Software Foundation.
  3560. + */
  3561. +
  3562. +#include <linux/mtd/mtd.h>
  3563. +#include <linux/mtd/partitions.h>
  3564. +
  3565. +#include <asm/mach-ar71xx/ar71xx.h>
  3566. +
  3567. +#include "machtype.h"
  3568. +#include "devices.h"
  3569. +#include "dev-m25p80.h"
  3570. +#include "dev-ar913x-wmac.h"
  3571. +#include "dev-gpio-buttons.h"
  3572. +#include "dev-leds-gpio.h"
  3573. +#include "nvram.h"
  3574. +
  3575. +#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */
  3576. +#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */
  3577. +#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */
  3578. +#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */
  3579. +#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */
  3580. +#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */
  3581. +#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */
  3582. +
  3583. +/* buttons may need refinement */
  3584. +
  3585. +#define DIR_615C1_GPIO_BTN_WPS 12
  3586. +#define DIR_615C1_GPIO_BTN_RESET 21
  3587. +
  3588. +#define DIR_615C1_BUTTONS_POLL_INTERVAL 20
  3589. +
  3590. +#define DIR_615C1_CONFIG_ADDR 0x1f020000
  3591. +#define DIR_615C1_CONFIG_SIZE 0x10000
  3592. +
  3593. +#ifdef CONFIG_MTD_PARTITIONS
  3594. +static struct mtd_partition dir_615c1_partitions[] = {
  3595. + {
  3596. + .name = "u-boot",
  3597. + .offset = 0,
  3598. + .size = 0x020000,
  3599. + .mask_flags = MTD_WRITEABLE,
  3600. + } , {
  3601. + .name = "config",
  3602. + .offset = 0x020000,
  3603. + .size = 0x010000,
  3604. + } , {
  3605. + .name = "kernel",
  3606. + .offset = 0x030000,
  3607. + .size = 0x0d0000,
  3608. + } , {
  3609. + .name = "rootfs",
  3610. + .offset = 0x100000,
  3611. + .size = 0x2f0000,
  3612. + } , {
  3613. + .name = "art",
  3614. + .offset = 0x3f0000,
  3615. + .size = 0x010000,
  3616. + .mask_flags = MTD_WRITEABLE,
  3617. + } , {
  3618. + .name = "firmware",
  3619. + .offset = 0x030000,
  3620. + .size = 0x3c0000,
  3621. + }
  3622. +};
  3623. +#endif /* CONFIG_MTD_PARTITIONS */
  3624. +
  3625. +static struct flash_platform_data dir_615c1_flash_data = {
  3626. +#ifdef CONFIG_MTD_PARTITIONS
  3627. + .parts = dir_615c1_partitions,
  3628. + .nr_parts = ARRAY_SIZE(dir_615c1_partitions),
  3629. +#endif
  3630. +};
  3631. +
  3632. +static struct gpio_led dir_615c1_leds_gpio[] __initdata = {
  3633. + {
  3634. + .name = "dir-615c1:orange:status",
  3635. + .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS,
  3636. + .active_low = 1,
  3637. + }, {
  3638. + .name = "dir-615c1:blue:wps",
  3639. + .gpio = DIR_615C1_GPIO_LED_BLUE_WPS,
  3640. + .active_low = 1,
  3641. + }, {
  3642. + .name = "dir-615c1:green:wan",
  3643. + .gpio = DIR_615C1_GPIO_LED_GREEN_WAN,
  3644. + .active_low = 1,
  3645. + }, {
  3646. + .name = "dir-615c1:green:wancpu",
  3647. + .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU,
  3648. + .active_low = 1,
  3649. + }, {
  3650. + .name = "dir-615c1:green:wlan",
  3651. + .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN,
  3652. + .active_low = 1,
  3653. + }, {
  3654. + .name = "dir-615c1:green:status",
  3655. + .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS,
  3656. + .active_low = 1,
  3657. + }, {
  3658. + .name = "dir-615c1:orange:wan",
  3659. + .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN,
  3660. + .active_low = 1,
  3661. + }
  3662. +
  3663. +};
  3664. +
  3665. +static struct gpio_button dir_615c1_gpio_buttons[] __initdata = {
  3666. + {
  3667. + .desc = "reset",
  3668. + .type = EV_KEY,
  3669. + .code = KEY_RESTART,
  3670. + .threshold = 3,
  3671. + .gpio = DIR_615C1_GPIO_BTN_RESET,
  3672. + }, {
  3673. + .desc = "wps",
  3674. + .type = EV_KEY,
  3675. + .code = KEY_WPS_BUTTON,
  3676. + .threshold = 3,
  3677. + .gpio = DIR_615C1_GPIO_BTN_WPS,
  3678. + }
  3679. +};
  3680. +
  3681. +#define DIR_615C1_LAN_PHYMASK BIT(0)
  3682. +#define DIR_615C1_WAN_PHYMASK BIT(4)
  3683. +#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \
  3684. + DIR_615C1_WAN_PHYMASK))
  3685. +
  3686. +static void __init dir_615c1_setup(void)
  3687. +{
  3688. + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR);
  3689. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3690. + u8 mac[6];
  3691. + u8 *wlan_mac = NULL;
  3692. +
  3693. + if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE,
  3694. + "lan_mac=", mac) == 0) {
  3695. + ar71xx_set_mac_base(mac);
  3696. + wlan_mac = mac;
  3697. + }
  3698. +
  3699. + ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK);
  3700. +
  3701. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3702. + ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK;
  3703. +
  3704. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3705. + ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK;
  3706. +
  3707. + ar71xx_add_device_eth(0);
  3708. + ar71xx_add_device_eth(1);
  3709. +
  3710. + ar71xx_add_device_m25p80(&dir_615c1_flash_data);
  3711. +
  3712. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio),
  3713. + dir_615c1_leds_gpio);
  3714. +
  3715. + ar71xx_add_device_gpio_buttons(-1, DIR_615C1_BUTTONS_POLL_INTERVAL,
  3716. + ARRAY_SIZE(dir_615c1_gpio_buttons),
  3717. + dir_615c1_gpio_buttons);
  3718. +
  3719. + ar913x_add_device_wmac(eeprom, wlan_mac);
  3720. +}
  3721. +
  3722. +MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1",
  3723. + dir_615c1_setup);
  3724. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c
  3725. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100
  3726. +++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-05-27 14:36:51.000000000 +0200
  3727. @@ -0,0 +1,192 @@
  3728. +/*
  3729. + * D-Link DIR-825 rev. B1 board support
  3730. + *
  3731. + * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o.
  3732. + *
  3733. + * based on mach-wndr3700.c
  3734. + *
  3735. + * This program is free software; you can redistribute it and/or modify it
  3736. + * under the terms of the GNU General Public License version 2 as published
  3737. + * by the Free Software Foundation.
  3738. + */
  3739. +
  3740. +#include <linux/platform_device.h>
  3741. +#include <linux/mtd/mtd.h>
  3742. +#include <linux/mtd/partitions.h>
  3743. +#include <linux/delay.h>
  3744. +#include <linux/rtl8366s.h>
  3745. +
  3746. +#include <asm/mach-ar71xx/ar71xx.h>
  3747. +
  3748. +#include "machtype.h"
  3749. +#include "devices.h"
  3750. +#include "dev-m25p80.h"
  3751. +#include "dev-ap94-pci.h"
  3752. +#include "dev-gpio-buttons.h"
  3753. +#include "dev-leds-gpio.h"
  3754. +#include "dev-usb.h"
  3755. +
  3756. +#define DIR825B1_GPIO_LED_BLUE_USB 0
  3757. +#define DIR825B1_GPIO_LED_ORANGE_POWER 1
  3758. +#define DIR825B1_GPIO_LED_BLUE_POWER 2
  3759. +#define DIR825B1_GPIO_LED_BLUE_POWERSAVE 4
  3760. +#define DIR825B1_GPIO_LED_ORANGE_PLANET 6
  3761. +#define DIR825B1_GPIO_LED_BLUE_PLANET 11
  3762. +
  3763. +#define DIR825B1_GPIO_BTN_RESET 3
  3764. +#define DIR825B1_GPIO_BTN_POWERSAVE 8
  3765. +
  3766. +#define DIR825B1_GPIO_RTL8366_SDA 5
  3767. +#define DIR825B1_GPIO_RTL8366_SCK 7
  3768. +
  3769. +#define DIR825B1_BUTTONS_POLL_INTERVAL 20
  3770. +
  3771. +#define DIR825B1_CAL_LOCATION_0 0x1f661000
  3772. +#define DIR825B1_CAL_LOCATION_1 0x1f665000
  3773. +
  3774. +#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8
  3775. +#define DIR825B1_MAC_LOCATION_1 0x2ffa8370
  3776. +
  3777. +#ifdef CONFIG_MTD_PARTITIONS
  3778. +static struct mtd_partition dir825b1_partitions[] = {
  3779. + {
  3780. + .name = "uboot",
  3781. + .offset = 0,
  3782. + .size = 0x040000,
  3783. + .mask_flags = MTD_WRITEABLE,
  3784. + } , {
  3785. + .name = "config",
  3786. + .offset = 0x040000,
  3787. + .size = 0x010000,
  3788. + .mask_flags = MTD_WRITEABLE,
  3789. + } , {
  3790. + .name = "firmware",
  3791. + .offset = 0x050000,
  3792. + .size = 0x610000,
  3793. + } , {
  3794. + .name = "caldata",
  3795. + .offset = 0x660000,
  3796. + .size = 0x010000,
  3797. + .mask_flags = MTD_WRITEABLE,
  3798. + } , {
  3799. + .name = "unknown",
  3800. + .offset = 0x670000,
  3801. + .size = 0x190000,
  3802. + .mask_flags = MTD_WRITEABLE,
  3803. + }
  3804. +};
  3805. +#endif /* CONFIG_MTD_PARTITIONS */
  3806. +
  3807. +static struct flash_platform_data dir825b1_flash_data = {
  3808. +#ifdef CONFIG_MTD_PARTITIONS
  3809. + .parts = dir825b1_partitions,
  3810. + .nr_parts = ARRAY_SIZE(dir825b1_partitions),
  3811. +#endif
  3812. +};
  3813. +
  3814. +static struct gpio_led dir825b1_leds_gpio[] __initdata = {
  3815. + {
  3816. + .name = "dir825b1:blue:usb",
  3817. + .gpio = DIR825B1_GPIO_LED_BLUE_USB,
  3818. + .active_low = 1,
  3819. + }, {
  3820. + .name = "dir825b1:orange:power",
  3821. + .gpio = DIR825B1_GPIO_LED_ORANGE_POWER,
  3822. + .active_low = 1,
  3823. + }, {
  3824. + .name = "dir825b1:blue:power",
  3825. + .gpio = DIR825B1_GPIO_LED_BLUE_POWER,
  3826. + .active_low = 1,
  3827. + }, {
  3828. + .name = "dir825b1:blue:powersave",
  3829. + .gpio = DIR825B1_GPIO_LED_BLUE_POWERSAVE,
  3830. + .active_low = 1,
  3831. + }, {
  3832. + .name = "dir825b1:orange:planet",
  3833. + .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET,
  3834. + .active_low = 1,
  3835. + }, {
  3836. + .name = "dir825b1:blue:planet",
  3837. + .gpio = DIR825B1_GPIO_LED_BLUE_PLANET,
  3838. + .active_low = 1,
  3839. + }
  3840. +};
  3841. +
  3842. +static struct gpio_button dir825b1_gpio_buttons[] __initdata = {
  3843. + {
  3844. + .desc = "reset",
  3845. + .type = EV_KEY,
  3846. + .code = KEY_RESTART,
  3847. + .threshold = 3,
  3848. + .gpio = DIR825B1_GPIO_BTN_RESET,
  3849. + .active_low = 1,
  3850. + } , {
  3851. + .desc = "powersave",
  3852. + .type = EV_KEY,
  3853. + .code = BTN_1,
  3854. + .threshold = 3,
  3855. + .gpio = DIR825B1_GPIO_BTN_POWERSAVE,
  3856. + .active_low = 1,
  3857. + }
  3858. +};
  3859. +
  3860. +static struct rtl8366s_platform_data dir825b1_rtl8366s_data = {
  3861. + .gpio_sda = DIR825B1_GPIO_RTL8366_SDA,
  3862. + .gpio_sck = DIR825B1_GPIO_RTL8366_SCK,
  3863. +};
  3864. +
  3865. +static struct platform_device dir825b1_rtl8366s_device = {
  3866. + .name = RTL8366S_DRIVER_NAME,
  3867. + .id = -1,
  3868. + .dev = {
  3869. + .platform_data = &dir825b1_rtl8366s_data,
  3870. + }
  3871. +};
  3872. +
  3873. +static void __init dir825b1_setup(void)
  3874. +{
  3875. + u8 mac[6], i;
  3876. +
  3877. + memcpy(mac, (u8*)KSEG1ADDR(DIR825B1_MAC_LOCATION_1), 6);
  3878. + for(i = 5; i >= 3; i--)
  3879. + if(++mac[i] != 0x00) break;
  3880. +
  3881. + ar71xx_set_mac_base(mac);
  3882. +
  3883. + ar71xx_add_device_mdio(0x0);
  3884. +
  3885. + ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3886. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3887. + ar71xx_eth0_data.speed = SPEED_1000;
  3888. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3889. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  3890. +
  3891. + ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3892. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3893. + ar71xx_eth1_data.phy_mask = 0x10;
  3894. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  3895. +
  3896. + ar71xx_add_device_eth(0);
  3897. + ar71xx_add_device_eth(1);
  3898. +
  3899. + ar71xx_add_device_m25p80(&dir825b1_flash_data);
  3900. +
  3901. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio),
  3902. + dir825b1_leds_gpio);
  3903. +
  3904. + ar71xx_add_device_gpio_buttons(-1, DIR825B1_BUTTONS_POLL_INTERVAL,
  3905. + ARRAY_SIZE(dir825b1_gpio_buttons),
  3906. + dir825b1_gpio_buttons);
  3907. +
  3908. + ar71xx_add_device_usb();
  3909. +
  3910. + platform_device_register(&dir825b1_rtl8366s_device);
  3911. +
  3912. + ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0),
  3913. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0),
  3914. + (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1),
  3915. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1));
  3916. +}
  3917. +
  3918. +MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1",
  3919. + dir825b1_setup);
  3920. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c
  3921. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100
  3922. +++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-05-27 14:36:51.000000000 +0200
  3923. @@ -0,0 +1,165 @@
  3924. +/*
  3925. + * Planex MZK-W04NU board support
  3926. + *
  3927. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  3928. + *
  3929. + * This program is free software; you can redistribute it and/or modify it
  3930. + * under the terms of the GNU General Public License version 2 as published
  3931. + * by the Free Software Foundation.
  3932. + */
  3933. +
  3934. +#include <linux/mtd/mtd.h>
  3935. +#include <linux/mtd/partitions.h>
  3936. +
  3937. +#include <asm/mach-ar71xx/ar71xx.h>
  3938. +
  3939. +#include "machtype.h"
  3940. +#include "devices.h"
  3941. +#include "dev-ar913x-wmac.h"
  3942. +#include "dev-gpio-buttons.h"
  3943. +#include "dev-leds-gpio.h"
  3944. +#include "dev-m25p80.h"
  3945. +#include "dev-usb.h"
  3946. +
  3947. +#define MZK_W04NU_GPIO_LED_USB 0
  3948. +#define MZK_W04NU_GPIO_LED_STATUS 1
  3949. +#define MZK_W04NU_GPIO_LED_WPS 3
  3950. +#define MZK_W04NU_GPIO_LED_WLAN 6
  3951. +#define MZK_W04NU_GPIO_LED_AP 15
  3952. +#define MZK_W04NU_GPIO_LED_ROUTER 16
  3953. +
  3954. +#define MZK_W04NU_GPIO_BTN_APROUTER 5
  3955. +#define MZK_W04NU_GPIO_BTN_WPS 12
  3956. +#define MZK_W04NU_GPIO_BTN_RESET 21
  3957. +
  3958. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  3959. +
  3960. +#ifdef CONFIG_MTD_PARTITIONS
  3961. +static struct mtd_partition mzk_w04nu_partitions[] = {
  3962. + {
  3963. + .name = "u-boot",
  3964. + .offset = 0,
  3965. + .size = 0x040000,
  3966. + .mask_flags = MTD_WRITEABLE,
  3967. + } , {
  3968. + .name = "u-boot-env",
  3969. + .offset = 0x040000,
  3970. + .size = 0x010000,
  3971. + } , {
  3972. + .name = "kernel",
  3973. + .offset = 0x050000,
  3974. + .size = 0x160000,
  3975. + } , {
  3976. + .name = "rootfs",
  3977. + .offset = 0x1b0000,
  3978. + .size = 0x630000,
  3979. + } , {
  3980. + .name = "art",
  3981. + .offset = 0x7e0000,
  3982. + .size = 0x020000,
  3983. + .mask_flags = MTD_WRITEABLE,
  3984. + } , {
  3985. + .name = "firmware",
  3986. + .offset = 0x050000,
  3987. + .size = 0x790000,
  3988. + }
  3989. +};
  3990. +#endif /* CONFIG_MTD_PARTITIONS */
  3991. +
  3992. +static struct flash_platform_data mzk_w04nu_flash_data = {
  3993. +#ifdef CONFIG_MTD_PARTITIONS
  3994. + .parts = mzk_w04nu_partitions,
  3995. + .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions),
  3996. +#endif
  3997. +};
  3998. +
  3999. +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
  4000. + {
  4001. + .name = "mzk-w04nu:green:status",
  4002. + .gpio = MZK_W04NU_GPIO_LED_STATUS,
  4003. + .active_low = 1,
  4004. + }, {
  4005. + .name = "mzk-w04nu:blue:wps",
  4006. + .gpio = MZK_W04NU_GPIO_LED_WPS,
  4007. + .active_low = 1,
  4008. + }, {
  4009. + .name = "mzk-w04nu:green:wlan",
  4010. + .gpio = MZK_W04NU_GPIO_LED_WLAN,
  4011. + .active_low = 1,
  4012. + }, {
  4013. + .name = "mzk-w04nu:green:usb",
  4014. + .gpio = MZK_W04NU_GPIO_LED_USB,
  4015. + .active_low = 1,
  4016. + }, {
  4017. + .name = "mzk-w04nu:green:ap",
  4018. + .gpio = MZK_W04NU_GPIO_LED_AP,
  4019. + .active_low = 1,
  4020. + }, {
  4021. + .name = "mzk-w04nu:green:router",
  4022. + .gpio = MZK_W04NU_GPIO_LED_ROUTER,
  4023. + .active_low = 1,
  4024. + }
  4025. +};
  4026. +
  4027. +static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = {
  4028. + {
  4029. + .desc = "reset",
  4030. + .type = EV_KEY,
  4031. + .code = KEY_RESTART,
  4032. + .threshold = 3,
  4033. + .gpio = MZK_W04NU_GPIO_BTN_RESET,
  4034. + .active_low = 1,
  4035. + }, {
  4036. + .desc = "wps",
  4037. + .type = EV_KEY,
  4038. + .code = KEY_WPS_BUTTON,
  4039. + .threshold = 3,
  4040. + .gpio = MZK_W04NU_GPIO_BTN_WPS,
  4041. + .active_low = 1,
  4042. + }, {
  4043. + .desc = "aprouter",
  4044. + .type = EV_KEY,
  4045. + .code = BTN_2,
  4046. + .threshold = 3,
  4047. + .gpio = MZK_W04NU_GPIO_BTN_APROUTER,
  4048. + .active_low = 0,
  4049. + }
  4050. +};
  4051. +
  4052. +#define MZK_W04NU_WAN_PHYMASK BIT(4)
  4053. +#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK)
  4054. +
  4055. +static void __init mzk_w04nu_setup(void)
  4056. +{
  4057. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4058. +
  4059. + ar71xx_set_mac_base(eeprom);
  4060. +
  4061. + ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK);
  4062. +
  4063. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4064. + ar71xx_eth0_data.speed = SPEED_100;
  4065. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4066. + ar71xx_eth0_data.has_ar8216 = 1;
  4067. +
  4068. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4069. + ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK;
  4070. +
  4071. + ar71xx_add_device_eth(0);
  4072. + ar71xx_add_device_eth(1);
  4073. +
  4074. + ar71xx_add_device_m25p80(&mzk_w04nu_flash_data);
  4075. +
  4076. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
  4077. + mzk_w04nu_leds_gpio);
  4078. +
  4079. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4080. + ARRAY_SIZE(mzk_w04nu_gpio_buttons),
  4081. + mzk_w04nu_gpio_buttons);
  4082. + ar71xx_add_device_usb();
  4083. +
  4084. + ar913x_add_device_wmac(eeprom, NULL);
  4085. +}
  4086. +
  4087. +MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU",
  4088. + mzk_w04nu_setup);
  4089. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c
  4090. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100
  4091. +++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-05-27 14:36:51.000000000 +0200
  4092. @@ -0,0 +1,158 @@
  4093. +/*
  4094. + * Planex MZK-W300NH board support
  4095. + *
  4096. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4097. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4098. + *
  4099. + * This program is free software; you can redistribute it and/or modify it
  4100. + * under the terms of the GNU General Public License version 2 as published
  4101. + * by the Free Software Foundation.
  4102. + */
  4103. +
  4104. +#include <linux/mtd/mtd.h>
  4105. +#include <linux/mtd/partitions.h>
  4106. +
  4107. +#include <asm/mach-ar71xx/ar71xx.h>
  4108. +
  4109. +#include "machtype.h"
  4110. +#include "devices.h"
  4111. +#include "dev-m25p80.h"
  4112. +#include "dev-ar913x-wmac.h"
  4113. +#include "dev-gpio-buttons.h"
  4114. +#include "dev-leds-gpio.h"
  4115. +
  4116. +#define MZK_W300NH_GPIO_LED_STATUS 1
  4117. +#define MZK_W300NH_GPIO_LED_WPS 3
  4118. +#define MZK_W300NH_GPIO_LED_WLAN 6
  4119. +#define MZK_W300NH_GPIO_LED_AP 15
  4120. +#define MZK_W300NH_GPIO_LED_ROUTER 16
  4121. +
  4122. +#define MZK_W300NH_GPIO_BTN_APROUTER 5
  4123. +#define MZK_W300NH_GPIO_BTN_WPS 12
  4124. +#define MZK_W300NH_GPIO_BTN_RESET 21
  4125. +
  4126. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  4127. +
  4128. +#ifdef CONFIG_MTD_PARTITIONS
  4129. +static struct mtd_partition mzk_w300nh_partitions[] = {
  4130. + {
  4131. + .name = "u-boot",
  4132. + .offset = 0,
  4133. + .size = 0x040000,
  4134. + .mask_flags = MTD_WRITEABLE,
  4135. + } , {
  4136. + .name = "u-boot-env",
  4137. + .offset = 0x040000,
  4138. + .size = 0x010000,
  4139. + } , {
  4140. + .name = "kernel",
  4141. + .offset = 0x050000,
  4142. + .size = 0x160000,
  4143. + } , {
  4144. + .name = "rootfs",
  4145. + .offset = 0x1b0000,
  4146. + .size = 0x630000,
  4147. + } , {
  4148. + .name = "art",
  4149. + .offset = 0x7e0000,
  4150. + .size = 0x020000,
  4151. + .mask_flags = MTD_WRITEABLE,
  4152. + } , {
  4153. + .name = "firmware",
  4154. + .offset = 0x050000,
  4155. + .size = 0x790000,
  4156. + }
  4157. +};
  4158. +#endif /* CONFIG_MTD_PARTITIONS */
  4159. +
  4160. +static struct flash_platform_data mzk_w300nh_flash_data = {
  4161. +#ifdef CONFIG_MTD_PARTITIONS
  4162. + .parts = mzk_w300nh_partitions,
  4163. + .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions),
  4164. +#endif
  4165. +};
  4166. +
  4167. +static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = {
  4168. + {
  4169. + .name = "mzk-w300nh:green:status",
  4170. + .gpio = MZK_W300NH_GPIO_LED_STATUS,
  4171. + .active_low = 1,
  4172. + }, {
  4173. + .name = "mzk-w300nh:blue:wps",
  4174. + .gpio = MZK_W300NH_GPIO_LED_WPS,
  4175. + .active_low = 1,
  4176. + }, {
  4177. + .name = "mzk-w300nh:green:wlan",
  4178. + .gpio = MZK_W300NH_GPIO_LED_WLAN,
  4179. + .active_low = 1,
  4180. + }, {
  4181. + .name = "mzk-w300nh:green:ap",
  4182. + .gpio = MZK_W300NH_GPIO_LED_AP,
  4183. + .active_low = 1,
  4184. + }, {
  4185. + .name = "mzk-w300nh:green:router",
  4186. + .gpio = MZK_W300NH_GPIO_LED_ROUTER,
  4187. + .active_low = 1,
  4188. + }
  4189. +};
  4190. +
  4191. +static struct gpio_button mzk_w300nh_gpio_buttons[] __initdata = {
  4192. + {
  4193. + .desc = "reset",
  4194. + .type = EV_KEY,
  4195. + .code = KEY_RESTART,
  4196. + .threshold = 3,
  4197. + .gpio = MZK_W300NH_GPIO_BTN_RESET,
  4198. + .active_low = 1,
  4199. + }, {
  4200. + .desc = "wps",
  4201. + .type = EV_KEY,
  4202. + .code = KEY_WPS_BUTTON,
  4203. + .threshold = 3,
  4204. + .gpio = MZK_W300NH_GPIO_BTN_WPS,
  4205. + .active_low = 1,
  4206. + }, {
  4207. + .desc = "aprouter",
  4208. + .type = EV_KEY,
  4209. + .code = BTN_2,
  4210. + .threshold = 3,
  4211. + .gpio = MZK_W300NH_GPIO_BTN_APROUTER,
  4212. + .active_low = 0,
  4213. + }
  4214. +};
  4215. +
  4216. +#define MZK_W300NH_WAN_PHYMASK BIT(4)
  4217. +#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK)
  4218. +
  4219. +static void __init mzk_w300nh_setup(void)
  4220. +{
  4221. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4222. +
  4223. + ar71xx_set_mac_base(eeprom);
  4224. +
  4225. + ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK);
  4226. +
  4227. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4228. + ar71xx_eth0_data.speed = SPEED_100;
  4229. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4230. + ar71xx_eth0_data.has_ar8216 = 1;
  4231. +
  4232. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4233. + ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK;
  4234. +
  4235. + ar71xx_add_device_eth(0);
  4236. + ar71xx_add_device_eth(1);
  4237. +
  4238. + ar71xx_add_device_m25p80(&mzk_w300nh_flash_data);
  4239. +
  4240. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio),
  4241. + mzk_w300nh_leds_gpio);
  4242. +
  4243. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4244. + ARRAY_SIZE(mzk_w300nh_gpio_buttons),
  4245. + mzk_w300nh_gpio_buttons);
  4246. + ar913x_add_device_wmac(eeprom, NULL);
  4247. +}
  4248. +
  4249. +MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH",
  4250. + mzk_w300nh_setup);
  4251. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c
  4252. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100
  4253. +++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-05-27 14:36:51.000000000 +0200
  4254. @@ -0,0 +1,222 @@
  4255. +/*
  4256. + * Zyxel NBG 460N/550N/550NH board support
  4257. + *
  4258. + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
  4259. + *
  4260. + * based on mach-tl-wr1043nd.c
  4261. + *
  4262. + * This program is free software; you can redistribute it and/or modify it
  4263. + * under the terms of the GNU General Public License version 2 as published
  4264. + * by the Free Software Foundation.
  4265. + */
  4266. +
  4267. +#include <linux/platform_device.h>
  4268. +#include <linux/mtd/mtd.h>
  4269. +#include <linux/mtd/partitions.h>
  4270. +#include <linux/delay.h>
  4271. +#include <linux/rtl8366s.h>
  4272. +
  4273. +#include <linux/i2c.h>
  4274. +#include <linux/i2c-algo-bit.h>
  4275. +#include <linux/i2c-gpio.h>
  4276. +
  4277. +#include <asm/mach-ar71xx/ar71xx.h>
  4278. +
  4279. +#include "machtype.h"
  4280. +#include "devices.h"
  4281. +#include "dev-m25p80.h"
  4282. +#include "dev-ar913x-wmac.h"
  4283. +#include "dev-gpio-buttons.h"
  4284. +#include "dev-leds-gpio.h"
  4285. +
  4286. +/* LEDs */
  4287. +#define NBG460N_GPIO_LED_WPS 3
  4288. +#define NBG460N_GPIO_LED_WAN 6
  4289. +#define NBG460N_GPIO_LED_POWER 14
  4290. +#define NBG460N_GPIO_LED_WLAN 15
  4291. +
  4292. +/* Buttons */
  4293. +#define NBG460N_GPIO_BTN_WPS 12
  4294. +#define NBG460N_GPIO_BTN_RESET 21
  4295. +#define NBG460N_BUTTONS_POLL_INTERVAL 20
  4296. +
  4297. +/* RTC chip PCF8563 I2C interface */
  4298. +#define NBG460N_GPIO_PCF8563_SDA 8
  4299. +#define NBG460N_GPIO_PCF8563_SCK 7
  4300. +
  4301. +/* Switch configuration I2C interface */
  4302. +#define NBG460N_GPIO_RTL8366_SDA 16
  4303. +#define NBG460N_GPIO_RTL8366_SCK 18
  4304. +
  4305. +#ifdef CONFIG_MTD_PARTITIONS
  4306. +static struct mtd_partition nbg460n_partitions[] = {
  4307. + {
  4308. + .name = "Bootbase",
  4309. + .offset = 0,
  4310. + .size = 0x010000,
  4311. + .mask_flags = MTD_WRITEABLE,
  4312. + } , {
  4313. + .name = "U-Boot Config",
  4314. + .offset = 0x010000,
  4315. + .size = 0x030000,
  4316. + } , {
  4317. + .name = "U-Boot",
  4318. + .offset = 0x040000,
  4319. + .size = 0x030000,
  4320. + } , {
  4321. + .name = "linux",
  4322. + .offset = 0x070000,
  4323. + .size = 0x0e0000,
  4324. + } , {
  4325. + .name = "rootfs",
  4326. + .offset = 0x150000,
  4327. + .size = 0x2a0000,
  4328. + } , {
  4329. + .name = "CalibData",
  4330. + .offset = 0x3f0000,
  4331. + .size = 0x010000,
  4332. + .mask_flags = MTD_WRITEABLE,
  4333. + } , {
  4334. + .name = "firmware",
  4335. + .offset = 0x070000,
  4336. + .size = 0x380000,
  4337. + }
  4338. +};
  4339. +#endif /* CONFIG_MTD_PARTITIONS */
  4340. +
  4341. +static struct flash_platform_data nbg460n_flash_data = {
  4342. +#ifdef CONFIG_MTD_PARTITIONS
  4343. + .parts = nbg460n_partitions,
  4344. + .nr_parts = ARRAY_SIZE(nbg460n_partitions),
  4345. +#endif
  4346. +};
  4347. +
  4348. +static struct gpio_led nbg460n_leds_gpio[] __initdata = {
  4349. + {
  4350. + .name = "nbg460n:green:power",
  4351. + .gpio = NBG460N_GPIO_LED_POWER,
  4352. + .active_low = 0,
  4353. + .default_trigger = "default-on",
  4354. + }, {
  4355. + .name = "nbg460n:green:wps",
  4356. + .gpio = NBG460N_GPIO_LED_WPS,
  4357. + .active_low = 0,
  4358. + }, {
  4359. + .name = "nbg460n:green:wlan",
  4360. + .gpio = NBG460N_GPIO_LED_WLAN,
  4361. + .active_low = 0,
  4362. + }, {
  4363. + /* Not really for controlling the LED,
  4364. + when set low the LED blinks uncontrollable */
  4365. + .name = "nbg460n:green:wan",
  4366. + .gpio = NBG460N_GPIO_LED_WAN,
  4367. + .active_low = 0,
  4368. + }
  4369. +};
  4370. +
  4371. +static struct gpio_button nbg460n_gpio_buttons[] __initdata = {
  4372. + {
  4373. + .desc = "reset",
  4374. + .type = EV_KEY,
  4375. + .code = KEY_RESTART,
  4376. + .threshold = 3,
  4377. + .gpio = NBG460N_GPIO_BTN_RESET,
  4378. + .active_low = 1,
  4379. + }, {
  4380. + .desc = "wps",
  4381. + .type = EV_KEY,
  4382. + .code = KEY_WPS_BUTTON,
  4383. + .threshold = 3,
  4384. + .gpio = NBG460N_GPIO_BTN_WPS,
  4385. + .active_low = 1,
  4386. + }
  4387. +};
  4388. +
  4389. +static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = {
  4390. + .sda_pin = NBG460N_GPIO_PCF8563_SDA,
  4391. + .scl_pin = NBG460N_GPIO_PCF8563_SCK,
  4392. + .udelay = 10,
  4393. +};
  4394. +
  4395. +static struct platform_device nbg460n_i2c_device = {
  4396. + .name = "i2c-gpio",
  4397. + .id = -1,
  4398. + .num_resources = 0,
  4399. + .resource = NULL,
  4400. + .dev = {
  4401. + .platform_data = &nbg460n_i2c_device_platdata,
  4402. + },
  4403. +};
  4404. +
  4405. +static struct i2c_board_info nbg460n_i2c_devs[] __initdata = {
  4406. + {
  4407. + I2C_BOARD_INFO("pcf8563", 0x51),
  4408. + },
  4409. +};
  4410. +
  4411. +static void __devinit nbg460n_i2c_init(void)
  4412. +{
  4413. + /* The gpio interface */
  4414. + platform_device_register(&nbg460n_i2c_device);
  4415. + /* I2C devices */
  4416. + i2c_register_board_info(0, nbg460n_i2c_devs,
  4417. + ARRAY_SIZE(nbg460n_i2c_devs));
  4418. +}
  4419. +
  4420. +
  4421. +static struct rtl8366s_platform_data nbg460n_rtl8366s_data = {
  4422. + .gpio_sda = NBG460N_GPIO_RTL8366_SDA,
  4423. + .gpio_sck = NBG460N_GPIO_RTL8366_SCK,
  4424. +};
  4425. +
  4426. +static struct platform_device nbg460n_rtl8366s_device = {
  4427. + .name = RTL8366S_DRIVER_NAME,
  4428. + .id = -1,
  4429. + .dev = {
  4430. + .platform_data = &nbg460n_rtl8366s_data,
  4431. + }
  4432. +};
  4433. +
  4434. +static void __init nbg460n_setup(void)
  4435. +{
  4436. + /* end of bootloader sector contains mac address*/
  4437. + u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8);
  4438. + /* last sector contains wlan calib data */
  4439. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4440. +
  4441. + ar71xx_set_mac_base(mac);
  4442. +
  4443. + /* LAN Port */
  4444. + ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4445. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4446. + ar71xx_eth0_data.speed = SPEED_1000;
  4447. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4448. +
  4449. + /* WAN Port */
  4450. + ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4451. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4452. + ar71xx_eth1_data.phy_mask = 0x10;
  4453. +
  4454. + ar71xx_add_device_eth(0);
  4455. + ar71xx_add_device_eth(1);
  4456. +
  4457. + /* register the switch phy */
  4458. + platform_device_register(&nbg460n_rtl8366s_device);
  4459. +
  4460. + /* register flash */
  4461. + ar71xx_add_device_m25p80(&nbg460n_flash_data);
  4462. +
  4463. + ar913x_add_device_wmac(eeprom, mac);
  4464. +
  4465. + /* register RTC chip */
  4466. + nbg460n_i2c_init();
  4467. +
  4468. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio),
  4469. + nbg460n_leds_gpio);
  4470. +
  4471. + ar71xx_add_device_gpio_buttons(-1, NBG460N_BUTTONS_POLL_INTERVAL,
  4472. + ARRAY_SIZE(nbg460n_gpio_buttons),
  4473. + nbg460n_gpio_buttons);
  4474. +}
  4475. +
  4476. +MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", nbg460n_setup);
  4477. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c
  4478. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100
  4479. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-05-27 14:36:51.000000000 +0200
  4480. @@ -0,0 +1,71 @@
  4481. +/*
  4482. + * Atheros PB42 board support
  4483. + *
  4484. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4485. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4486. + *
  4487. + * This program is free software; you can redistribute it and/or modify it
  4488. + * under the terms of the GNU General Public License version 2 as published
  4489. + * by the Free Software Foundation.
  4490. + */
  4491. +
  4492. +#include <asm/mach-ar71xx/ar71xx.h>
  4493. +
  4494. +#include "machtype.h"
  4495. +#include "devices.h"
  4496. +#include "dev-m25p80.h"
  4497. +#include "dev-gpio-buttons.h"
  4498. +#include "dev-pb42-pci.h"
  4499. +#include "dev-usb.h"
  4500. +
  4501. +#define PB42_BUTTONS_POLL_INTERVAL 20
  4502. +
  4503. +#define PB42_GPIO_BTN_SW4 8
  4504. +#define PB42_GPIO_BTN_SW5 3
  4505. +
  4506. +static struct gpio_button pb42_gpio_buttons[] __initdata = {
  4507. + {
  4508. + .desc = "sw4",
  4509. + .type = EV_KEY,
  4510. + .code = BTN_0,
  4511. + .threshold = 3,
  4512. + .gpio = PB42_GPIO_BTN_SW4,
  4513. + .active_low = 1,
  4514. + } , {
  4515. + .desc = "sw5",
  4516. + .type = EV_KEY,
  4517. + .code = BTN_1,
  4518. + .threshold = 3,
  4519. + .gpio = PB42_GPIO_BTN_SW5,
  4520. + .active_low = 1,
  4521. + }
  4522. +};
  4523. +
  4524. +#define PB42_WAN_PHYMASK BIT(20)
  4525. +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  4526. +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
  4527. +
  4528. +static void __init pb42_init(void)
  4529. +{
  4530. + ar71xx_add_device_m25p80(NULL);
  4531. +
  4532. + ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
  4533. +
  4534. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  4535. + ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
  4536. +
  4537. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4538. + ar71xx_eth1_data.speed = SPEED_100;
  4539. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4540. +
  4541. + ar71xx_add_device_eth(0);
  4542. + ar71xx_add_device_eth(1);
  4543. +
  4544. + ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL,
  4545. + ARRAY_SIZE(pb42_gpio_buttons),
  4546. + pb42_gpio_buttons);
  4547. +
  4548. + pb42_pci_init();
  4549. +}
  4550. +
  4551. +MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init);
  4552. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c
  4553. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100
  4554. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-05-27 14:36:51.000000000 +0200
  4555. @@ -0,0 +1,207 @@
  4556. +/*
  4557. + * Atheros PB44 board support
  4558. + *
  4559. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  4560. + *
  4561. + * This program is free software; you can redistribute it and/or modify it
  4562. + * under the terms of the GNU General Public License version 2 as published
  4563. + * by the Free Software Foundation.
  4564. + */
  4565. +
  4566. +#include <linux/init.h>
  4567. +#include <linux/bitops.h>
  4568. +#include <linux/delay.h>
  4569. +#include <linux/platform_device.h>
  4570. +#include <linux/spi/spi.h>
  4571. +#include <linux/spi/flash.h>
  4572. +#include <linux/spi/vsc7385.h>
  4573. +#include <linux/i2c.h>
  4574. +#include <linux/i2c-gpio.h>
  4575. +#include <linux/i2c/pcf857x.h>
  4576. +
  4577. +#include <asm/mach-ar71xx/ar71xx.h>
  4578. +
  4579. +#include "machtype.h"
  4580. +#include "devices.h"
  4581. +#include "dev-pb42-pci.h"
  4582. +#include "dev-gpio-buttons.h"
  4583. +#include "dev-leds-gpio.h"
  4584. +#include "dev-usb.h"
  4585. +
  4586. +#define PB44_PCF8757_VSC7395_CS 0
  4587. +#define PB44_PCF8757_STEREO_CS 1
  4588. +#define PB44_PCF8757_SLIC_CS0 2
  4589. +#define PB44_PCF8757_SLIC_TEST 3
  4590. +#define PB44_PCF8757_SLIC_INT0 4
  4591. +#define PB44_PCF8757_SLIC_INT1 5
  4592. +#define PB44_PCF8757_SW_RESET 6
  4593. +#define PB44_PCF8757_SW_JUMP 8
  4594. +#define PB44_PCF8757_LED_JUMP1 9
  4595. +#define PB44_PCF8757_LED_JUMP2 10
  4596. +#define PB44_PCF8757_TP24 11
  4597. +#define PB44_PCF8757_TP25 12
  4598. +#define PB44_PCF8757_TP26 13
  4599. +#define PB44_PCF8757_TP27 14
  4600. +#define PB44_PCF8757_TP28 15
  4601. +
  4602. +#define PB44_GPIO_I2C_SCL 0
  4603. +#define PB44_GPIO_I2C_SDA 1
  4604. +
  4605. +#define PB44_GPIO_EXP_BASE 16
  4606. +#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS)
  4607. +#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET)
  4608. +#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP)
  4609. +#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1)
  4610. +#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2)
  4611. +
  4612. +static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
  4613. + .sda_pin = PB44_GPIO_I2C_SDA,
  4614. + .scl_pin = PB44_GPIO_I2C_SCL,
  4615. +};
  4616. +
  4617. +static struct platform_device pb44_i2c_gpio_device = {
  4618. + .name = "i2c-gpio",
  4619. + .id = 0,
  4620. + .dev = {
  4621. + .platform_data = &pb44_i2c_gpio_data,
  4622. + }
  4623. +};
  4624. +
  4625. +static struct pcf857x_platform_data pb44_pcf857x_data = {
  4626. + .gpio_base = PB44_GPIO_EXP_BASE,
  4627. +};
  4628. +
  4629. +static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
  4630. + {
  4631. + I2C_BOARD_INFO("pcf8575", 0x20),
  4632. + .platform_data = &pb44_pcf857x_data,
  4633. + },
  4634. +};
  4635. +
  4636. +static struct gpio_led pb44_leds_gpio[] __initdata = {
  4637. + {
  4638. + .name = "pb44:amber:jump1",
  4639. + .gpio = PB44_GPIO_LED_JUMP1,
  4640. + .active_low = 1,
  4641. + }, {
  4642. + .name = "pb44:green:jump2",
  4643. + .gpio = PB44_GPIO_LED_JUMP2,
  4644. + .active_low = 1,
  4645. + },
  4646. +};
  4647. +
  4648. +static struct gpio_button pb44_gpio_buttons[] __initdata = {
  4649. + {
  4650. + .desc = "soft_reset",
  4651. + .type = EV_KEY,
  4652. + .code = KEY_RESTART,
  4653. + .threshold = 3,
  4654. + .gpio = PB44_GPIO_SW_RESET,
  4655. + .active_low = 1,
  4656. + } , {
  4657. + .desc = "jumpstart",
  4658. + .type = EV_KEY,
  4659. + .code = KEY_WPS_BUTTON,
  4660. + .threshold = 3,
  4661. + .gpio = PB44_GPIO_SW_JUMP,
  4662. + .active_low = 1,
  4663. + }
  4664. +};
  4665. +
  4666. +static void pb44_vsc7395_reset(void)
  4667. +{
  4668. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  4669. + udelay(10);
  4670. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  4671. + mdelay(50);
  4672. +}
  4673. +
  4674. +static struct vsc7385_platform_data pb44_vsc7395_data = {
  4675. + .reset = pb44_vsc7395_reset,
  4676. + .ucode_name = "vsc7395_ucode_pb44.bin",
  4677. + .mac_cfg = {
  4678. + .tx_ipg = 6,
  4679. + .bit2 = 1,
  4680. + .clk_sel = 0,
  4681. + },
  4682. +};
  4683. +
  4684. +static struct spi_board_info pb44_spi_info[] = {
  4685. + {
  4686. + .bus_num = 0,
  4687. + .chip_select = 0,
  4688. + .max_speed_hz = 25000000,
  4689. + .modalias = "m25p80",
  4690. + }, {
  4691. + .bus_num = 0,
  4692. + .chip_select = 1,
  4693. + .max_speed_hz = 25000000,
  4694. + .modalias = "spi-vsc7385",
  4695. + .platform_data = &pb44_vsc7395_data,
  4696. + .controller_data = (void *) PB44_GPIO_VSC7395_CS,
  4697. + },
  4698. +};
  4699. +
  4700. +static struct resource pb44_spi_resources[] = {
  4701. + [0] = {
  4702. + .start = AR71XX_SPI_BASE,
  4703. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  4704. + .flags = IORESOURCE_MEM,
  4705. + },
  4706. +};
  4707. +
  4708. +static struct ar71xx_spi_platform_data pb44_spi_data = {
  4709. + .bus_num = 0,
  4710. + .num_chipselect = 2,
  4711. +};
  4712. +
  4713. +static struct platform_device pb44_spi_device = {
  4714. + .name = "pb44-spi",
  4715. + .id = -1,
  4716. + .resource = pb44_spi_resources,
  4717. + .num_resources = ARRAY_SIZE(pb44_spi_resources),
  4718. + .dev = {
  4719. + .platform_data = &pb44_spi_data,
  4720. + },
  4721. +};
  4722. +
  4723. +#define PB44_WAN_PHYMASK BIT(0)
  4724. +#define PB44_LAN_PHYMASK 0
  4725. +#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK)
  4726. +
  4727. +static void __init pb44_init(void)
  4728. +{
  4729. + ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK);
  4730. +
  4731. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4732. + ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK;
  4733. +
  4734. + ar71xx_add_device_eth(0);
  4735. +
  4736. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4737. + ar71xx_eth1_data.speed = SPEED_1000;
  4738. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4739. + ar71xx_eth1_pll_data.pll_1000 = 0x110000;
  4740. +
  4741. + ar71xx_add_device_eth(1);
  4742. +
  4743. + ar71xx_add_device_usb();
  4744. +
  4745. + pb42_pci_init();
  4746. +
  4747. + i2c_register_board_info(0, pb44_i2c_board_info,
  4748. + ARRAY_SIZE(pb44_i2c_board_info));
  4749. +
  4750. + platform_device_register(&pb44_i2c_gpio_device);
  4751. +
  4752. + spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info));
  4753. + platform_device_register(&pb44_spi_device);
  4754. +
  4755. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
  4756. + pb44_leds_gpio);
  4757. +
  4758. + ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(pb44_gpio_buttons),
  4759. + pb44_gpio_buttons);
  4760. +}
  4761. +
  4762. +MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init);
  4763. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c
  4764. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100
  4765. +++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-05-27 14:36:51.000000000 +0200
  4766. @@ -0,0 +1,109 @@
  4767. +/*
  4768. + * Atheros PB92 board support
  4769. + *
  4770. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  4771. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4772. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4773. + *
  4774. + * This program is free software; you can redistribute it and/or modify it
  4775. + * under the terms of the GNU General Public License version 2 as published
  4776. + * by the Free Software Foundation.
  4777. + */
  4778. +
  4779. +#include <linux/mtd/mtd.h>
  4780. +#include <linux/mtd/partitions.h>
  4781. +#include <asm/mach-ar71xx/ar71xx.h>
  4782. +
  4783. +#include "machtype.h"
  4784. +#include "devices.h"
  4785. +#include "dev-m25p80.h"
  4786. +#include "dev-gpio-buttons.h"
  4787. +#include "dev-pb9x-pci.h"
  4788. +#include "dev-usb.h"
  4789. +
  4790. +#ifdef CONFIG_MTD_PARTITIONS
  4791. +static struct mtd_partition pb92_partitions[] = {
  4792. + {
  4793. + .name = "u-boot",
  4794. + .offset = 0,
  4795. + .size = 0x040000,
  4796. + .mask_flags = MTD_WRITEABLE,
  4797. + } , {
  4798. + .name = "u-boot-env",
  4799. + .offset = 0x040000,
  4800. + .size = 0x010000,
  4801. + } , {
  4802. + .name = "rootfs",
  4803. + .offset = 0x050000,
  4804. + .size = 0x2b0000,
  4805. + } , {
  4806. + .name = "uImage",
  4807. + .offset = 0x300000,
  4808. + .size = 0x0e0000,
  4809. + } , {
  4810. + .name = "ART",
  4811. + .offset = 0x3e0000,
  4812. + .size = 0x020000,
  4813. + .mask_flags = MTD_WRITEABLE,
  4814. + }
  4815. +};
  4816. +#endif /* CONFIG_MTD_PARTITIONS */
  4817. +
  4818. +static struct flash_platform_data pb92_flash_data = {
  4819. +#ifdef CONFIG_MTD_PARTITIONS
  4820. + .parts = pb92_partitions,
  4821. + .nr_parts = ARRAY_SIZE(pb92_partitions),
  4822. +#endif
  4823. +};
  4824. +
  4825. +
  4826. +#define PB92_BUTTONS_POLL_INTERVAL 20
  4827. +
  4828. +#define PB92_GPIO_BTN_SW4 8
  4829. +#define PB92_GPIO_BTN_SW5 3
  4830. +
  4831. +static struct gpio_button pb92_gpio_buttons[] __initdata = {
  4832. + {
  4833. + .desc = "sw4",
  4834. + .type = EV_KEY,
  4835. + .code = BTN_0,
  4836. + .threshold = 3,
  4837. + .gpio = PB92_GPIO_BTN_SW4,
  4838. + .active_low = 1,
  4839. + } , {
  4840. + .desc = "sw5",
  4841. + .type = EV_KEY,
  4842. + .code = BTN_1,
  4843. + .threshold = 3,
  4844. + .gpio = PB92_GPIO_BTN_SW5,
  4845. + .active_low = 1,
  4846. + }
  4847. +};
  4848. +
  4849. +static void __init pb92_init(void)
  4850. +{
  4851. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  4852. +
  4853. + ar71xx_set_mac_base(mac);
  4854. + ar71xx_add_device_m25p80(&pb92_flash_data);
  4855. +
  4856. + ar71xx_add_device_mdio(~0);
  4857. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4858. + ar71xx_eth0_data.speed = SPEED_1000;
  4859. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4860. +
  4861. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4862. + ar71xx_eth1_data.speed = SPEED_1000;
  4863. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4864. +
  4865. + ar71xx_add_device_eth(0);
  4866. + ar71xx_add_device_eth(1);
  4867. +
  4868. + ar71xx_add_device_gpio_buttons(-1, PB92_BUTTONS_POLL_INTERVAL,
  4869. + ARRAY_SIZE(pb92_gpio_buttons),
  4870. + pb92_gpio_buttons);
  4871. +
  4872. + pb9x_pci_init();
  4873. +}
  4874. +
  4875. +MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init);
  4876. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c
  4877. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100
  4878. +++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-05-27 14:36:51.000000000 +0200
  4879. @@ -0,0 +1,290 @@
  4880. +/*
  4881. + * MikroTik RouterBOARD 4xx series support
  4882. + *
  4883. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4884. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4885. + *
  4886. + * This program is free software; you can redistribute it and/or modify it
  4887. + * under the terms of the GNU General Public License version 2 as published
  4888. + * by the Free Software Foundation.
  4889. + */
  4890. +
  4891. +#include <linux/platform_device.h>
  4892. +#include <linux/irq.h>
  4893. +#include <linux/mmc/host.h>
  4894. +#include <linux/spi/spi.h>
  4895. +#include <linux/spi/flash.h>
  4896. +#include <linux/spi/mmc_spi.h>
  4897. +
  4898. +#include <asm/mach-ar71xx/ar71xx.h>
  4899. +#include <asm/mach-ar71xx/pci.h>
  4900. +
  4901. +#include "machtype.h"
  4902. +#include "devices.h"
  4903. +#include "dev-gpio-buttons.h"
  4904. +#include "dev-leds-gpio.h"
  4905. +#include "dev-usb.h"
  4906. +
  4907. +#define RB4XX_GPIO_USER_LED 4
  4908. +#define RB4XX_GPIO_RESET_SWITCH 7
  4909. +
  4910. +#define RB4XX_BUTTONS_POLL_INTERVAL 20
  4911. +
  4912. +static struct gpio_led rb4xx_leds_gpio[] __initdata = {
  4913. + {
  4914. + .name = "rb4xx:yellow:user",
  4915. + .gpio = RB4XX_GPIO_USER_LED,
  4916. + .active_low = 0,
  4917. + },
  4918. +};
  4919. +
  4920. +static struct gpio_button rb4xx_gpio_buttons[] __initdata = {
  4921. + {
  4922. + .desc = "reset_switch",
  4923. + .type = EV_KEY,
  4924. + .code = KEY_RESTART,
  4925. + .threshold = 3,
  4926. + .gpio = RB4XX_GPIO_RESET_SWITCH,
  4927. + .active_low = 1,
  4928. + }
  4929. +};
  4930. +
  4931. +static struct platform_device rb4xx_nand_device = {
  4932. + .name = "rb4xx-nand",
  4933. + .id = -1,
  4934. +};
  4935. +
  4936. +static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
  4937. + {
  4938. + .slot = 0,
  4939. + .pin = 1,
  4940. + .irq = AR71XX_PCI_IRQ_DEV2,
  4941. + }, {
  4942. + .slot = 1,
  4943. + .pin = 1,
  4944. + .irq = AR71XX_PCI_IRQ_DEV0,
  4945. + }, {
  4946. + .slot = 1,
  4947. + .pin = 2,
  4948. + .irq = AR71XX_PCI_IRQ_DEV1,
  4949. + }, {
  4950. + .slot = 2,
  4951. + .pin = 1,
  4952. + .irq = AR71XX_PCI_IRQ_DEV1,
  4953. + }, {
  4954. + .slot = 3,
  4955. + .pin = 1,
  4956. + .irq = AR71XX_PCI_IRQ_DEV2,
  4957. + }
  4958. +};
  4959. +
  4960. +#if 0
  4961. +/*
  4962. + * SPI device support is experimental
  4963. + */
  4964. +static struct flash_platform_data rb4xx_flash_data = {
  4965. + .type = "pm25lv512",
  4966. +};
  4967. +
  4968. +static struct spi_board_info rb4xx_spi_info[] = {
  4969. + {
  4970. + .bus_num = 0,
  4971. + .chip_select = 0,
  4972. + .max_speed_hz = 25000000,
  4973. + .modalias = "m25p80",
  4974. + .platform_data = &rb4xx_flash_data,
  4975. + }
  4976. +};
  4977. +
  4978. +static struct mmc_spi_platform_data rb433_mmc_data = {
  4979. + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
  4980. +};
  4981. +
  4982. +static struct spi_board_info rb433_spi_info[] = {
  4983. + {
  4984. + .bus_num = 0,
  4985. + .chip_select = 0,
  4986. + .max_speed_hz = 25000000,
  4987. + .modalias = "m25p80",
  4988. + .platform_data = &rb433_flash_data,
  4989. + }, {
  4990. + .bus_num = 0,
  4991. + .chip_select = 2,
  4992. + .max_speed_hz = 25000000,
  4993. + .modalias = "mmc_spi",
  4994. + .platform_data = &rb433_mmc_data,
  4995. + }
  4996. +};
  4997. +
  4998. +static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  4999. +{
  5000. + u32 ret;
  5001. +
  5002. + if (is_on == AR71XX_SPI_CS_INACTIVE) {
  5003. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5004. + } else {
  5005. + if (cs_high) {
  5006. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5007. + } else {
  5008. + if ((chip_select ^ 2) == 0)
  5009. + ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5010. + else
  5011. + ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5012. + }
  5013. + }
  5014. +
  5015. + return ret;
  5016. +}
  5017. +
  5018. +struct ar71xx_spi_platform_data rb433_spi_data = {
  5019. + .bus_num = 0,
  5020. + .num_chipselect = 3,
  5021. + .get_ioc_base = rb433_spi_get_ioc_base,
  5022. +};
  5023. +
  5024. +static void rb4xx_add_device_spi(void)
  5025. +{
  5026. + ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
  5027. +}
  5028. +
  5029. +static void rb433_add_device_spi(void)
  5030. +{
  5031. + ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info,
  5032. + ARRAY_SIZE(rb433_spi_info));
  5033. +}
  5034. +#else
  5035. +static inline void rb4xx_add_device_spi(void) {}
  5036. +static inline void rb433_add_device_spi(void) {}
  5037. +#endif
  5038. +
  5039. +static void __init rb4xx_generic_setup(void)
  5040. +{
  5041. + ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN |
  5042. + AR71XX_GPIO_FUNC_SPI_CS2_EN);
  5043. +
  5044. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
  5045. + rb4xx_leds_gpio);
  5046. +
  5047. + ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL,
  5048. + ARRAY_SIZE(rb4xx_gpio_buttons),
  5049. + rb4xx_gpio_buttons);
  5050. +
  5051. + platform_device_register(&rb4xx_nand_device);
  5052. +}
  5053. +
  5054. +static void __init rb411_setup(void)
  5055. +{
  5056. + rb4xx_generic_setup();
  5057. + rb4xx_add_device_spi();
  5058. +
  5059. + ar71xx_add_device_mdio(0xfffffffc);
  5060. +
  5061. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5062. + ar71xx_eth0_data.phy_mask = 0x00000003;
  5063. +
  5064. + ar71xx_add_device_eth(0);
  5065. +
  5066. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5067. +}
  5068. +
  5069. +MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH",
  5070. + rb411_setup);
  5071. +
  5072. +static void __init rb411u_setup(void)
  5073. +{
  5074. + rb411_setup();
  5075. + ar71xx_add_device_usb();
  5076. +}
  5077. +
  5078. +MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U",
  5079. + rb411u_setup);
  5080. +
  5081. +static void __init rb433_setup(void)
  5082. +{
  5083. + rb4xx_generic_setup();
  5084. + rb433_add_device_spi();
  5085. +
  5086. + ar71xx_add_device_mdio(0xffffffe9);
  5087. +
  5088. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5089. + ar71xx_eth0_data.speed = SPEED_100;
  5090. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5091. +
  5092. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5093. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5094. +
  5095. + ar71xx_add_device_eth(1);
  5096. + ar71xx_add_device_eth(0);
  5097. +
  5098. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5099. +}
  5100. +
  5101. +MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH",
  5102. + rb433_setup);
  5103. +
  5104. +static void __init rb433u_setup(void)
  5105. +{
  5106. + rb433_setup();
  5107. + ar71xx_add_device_usb();
  5108. +}
  5109. +
  5110. +MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH",
  5111. + rb433u_setup);
  5112. +
  5113. +static void __init rb450_generic_setup(int gige)
  5114. +{
  5115. + rb4xx_generic_setup();
  5116. + rb4xx_add_device_spi();
  5117. +
  5118. + ar71xx_add_device_mdio(0xffffffe0);
  5119. +
  5120. + ar71xx_eth0_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII;
  5121. + ar71xx_eth0_data.phy_mask = (gige) ? (1 << 0) : 0;
  5122. + ar71xx_eth0_data.speed = (gige) ? SPEED_1000 : SPEED_100;
  5123. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5124. +
  5125. + ar71xx_eth1_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII;
  5126. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5127. +
  5128. + ar71xx_add_device_eth(1);
  5129. + ar71xx_add_device_eth(0);
  5130. +}
  5131. +
  5132. +static void __init rb450_setup(void)
  5133. +{
  5134. + rb450_generic_setup(0);
  5135. +}
  5136. +
  5137. +MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450",
  5138. + rb450_setup);
  5139. +
  5140. +static void __init rb450g_setup(void)
  5141. +{
  5142. + rb450_generic_setup(1);
  5143. +}
  5144. +
  5145. +MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G",
  5146. + rb450g_setup);
  5147. +
  5148. +static void __init rb493_setup(void)
  5149. +{
  5150. + rb4xx_generic_setup();
  5151. + rb4xx_add_device_spi();
  5152. +
  5153. + ar71xx_add_device_mdio(0x3fffff00);
  5154. +
  5155. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5156. + ar71xx_eth0_data.speed = SPEED_100;
  5157. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5158. +
  5159. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5160. + ar71xx_eth1_data.phy_mask = 0x00000001;
  5161. +
  5162. + ar71xx_add_device_eth(0);
  5163. + ar71xx_add_device_eth(1);
  5164. +
  5165. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5166. +}
  5167. +
  5168. +MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH",
  5169. + rb493_setup);
  5170. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c
  5171. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100
  5172. +++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-05-27 14:36:51.000000000 +0200
  5173. @@ -0,0 +1,133 @@
  5174. +/*
  5175. + * MikroTik RouterBOARD 750 support
  5176. + *
  5177. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  5178. + *
  5179. + * This program is free software; you can redistribute it and/or modify it
  5180. + * under the terms of the GNU General Public License version 2 as published
  5181. + * by the Free Software Foundation.
  5182. + */
  5183. +
  5184. +#include <linux/platform_device.h>
  5185. +#include <asm/mach-ar71xx/ar71xx.h>
  5186. +#include <asm/mach-ar71xx/mach-rb750.h>
  5187. +
  5188. +#include "machtype.h"
  5189. +#include "dev-ap91-eth.h"
  5190. +
  5191. +static struct rb750_led_data rb750_leds[] = {
  5192. + {
  5193. + .name = "rb750:green:act",
  5194. + .mask = RB750_LED_ACT,
  5195. + .active_low = 1,
  5196. + }, {
  5197. + .name = "rb750:green:port1",
  5198. + .mask = RB750_LED_PORT5,
  5199. + .active_low = 1,
  5200. + }, {
  5201. + .name = "rb750:green:port2",
  5202. + .mask = RB750_LED_PORT4,
  5203. + .active_low = 1,
  5204. + }, {
  5205. + .name = "rb750:green:port3",
  5206. + .mask = RB750_LED_PORT3,
  5207. + .active_low = 1,
  5208. + }, {
  5209. + .name = "rb750:green:port4",
  5210. + .mask = RB750_LED_PORT2,
  5211. + .active_low = 1,
  5212. + }, {
  5213. + .name = "rb750:green:port5",
  5214. + .mask = RB750_LED_PORT1,
  5215. + .active_low = 1,
  5216. + }
  5217. +};
  5218. +
  5219. +static struct rb750_led_platform_data rb750_leds_data = {
  5220. + .num_leds = ARRAY_SIZE(rb750_leds),
  5221. + .leds = rb750_leds,
  5222. +};
  5223. +
  5224. +static struct platform_device rb750_leds_device = {
  5225. + .name = "leds-rb750",
  5226. + .dev = {
  5227. + .platform_data = &rb750_leds_data,
  5228. + }
  5229. +};
  5230. +
  5231. +static const char *rb750_port_names[AP91_ETH_NUM_PORT_NAMES] __initdata = {
  5232. + "port5",
  5233. + "port4",
  5234. + "port3",
  5235. + "port2",
  5236. +};
  5237. +
  5238. +static struct platform_device rb750_nand_device = {
  5239. + .name = "rb750-nand",
  5240. + .id = -1,
  5241. +};
  5242. +
  5243. +int rb750_latch_change(u32 mask_clr, u32 mask_set)
  5244. +{
  5245. + static DEFINE_SPINLOCK(lock);
  5246. + static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE;
  5247. + static u32 latch_oe;
  5248. + static u32 latch_clr;
  5249. + unsigned long flags;
  5250. + u32 t;
  5251. + int ret = 0;
  5252. +
  5253. + spin_lock_irqsave(&lock, flags);
  5254. +
  5255. + if ((mask_clr & BIT(31)) != 0 &&
  5256. + (latch_set & RB750_LVC573_LE) == 0) {
  5257. + goto unlock;
  5258. + }
  5259. +
  5260. + latch_set = (latch_set | mask_set) & ~mask_clr;
  5261. + latch_clr = (latch_clr | mask_clr) & ~mask_set;
  5262. +
  5263. + if (latch_oe == 0)
  5264. + latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE);
  5265. +
  5266. + if (likely(latch_set & RB750_LVC573_LE)) {
  5267. + void __iomem *base = ar71xx_gpio_base;
  5268. +
  5269. + t = __raw_readl(base + GPIO_REG_OE);
  5270. + t |= mask_clr | latch_oe | mask_set;
  5271. +
  5272. + __raw_writel(t, base + GPIO_REG_OE);
  5273. + __raw_writel(latch_clr, base + GPIO_REG_CLEAR);
  5274. + __raw_writel(latch_set, base + GPIO_REG_SET);
  5275. + } else if (mask_clr & RB750_LVC573_LE) {
  5276. + void __iomem *base = ar71xx_gpio_base;
  5277. +
  5278. + latch_oe = __raw_readl(base + GPIO_REG_OE);
  5279. + __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR);
  5280. + /* flush write */
  5281. + __raw_readl(base + GPIO_REG_CLEAR);
  5282. + }
  5283. +
  5284. + ret = 1;
  5285. +
  5286. + unlock:
  5287. + spin_unlock_irqrestore(&lock, flags);
  5288. + return ret;
  5289. +}
  5290. +EXPORT_SYMBOL_GPL(rb750_latch_change);
  5291. +
  5292. +static void __init rb750_setup(void)
  5293. +{
  5294. + ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
  5295. + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
  5296. + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
  5297. + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
  5298. + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
  5299. +
  5300. + ap91_eth_init(NULL, rb750_port_names);
  5301. + platform_device_register(&rb750_leds_device);
  5302. + platform_device_register(&rb750_nand_device);
  5303. +}
  5304. +
  5305. +MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750",
  5306. + rb750_setup);
  5307. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c
  5308. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100
  5309. +++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-05-27 14:36:51.000000000 +0200
  5310. @@ -0,0 +1,149 @@
  5311. +/*
  5312. + * TrendNET TEW-632BRP board support
  5313. + *
  5314. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  5315. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5316. + *
  5317. + * This program is free software; you can redistribute it and/or modify it
  5318. + * under the terms of the GNU General Public License version 2 as published
  5319. + * by the Free Software Foundation.
  5320. + */
  5321. +
  5322. +#include <linux/mtd/mtd.h>
  5323. +#include <linux/mtd/partitions.h>
  5324. +
  5325. +#include <asm/mach-ar71xx/ar71xx.h>
  5326. +
  5327. +#include "machtype.h"
  5328. +#include "devices.h"
  5329. +#include "dev-m25p80.h"
  5330. +#include "dev-ar913x-wmac.h"
  5331. +#include "dev-gpio-buttons.h"
  5332. +#include "dev-leds-gpio.h"
  5333. +#include "nvram.h"
  5334. +
  5335. +#define TEW_632BRP_GPIO_LED_STATUS 1
  5336. +#define TEW_632BRP_GPIO_LED_WPS 3
  5337. +#define TEW_632BRP_GPIO_LED_WLAN 6
  5338. +#define TEW_632BRP_GPIO_BTN_WPS 12
  5339. +#define TEW_632BRP_GPIO_BTN_RESET 21
  5340. +
  5341. +#define TEW_632BRP_BUTTONS_POLL_INTERVAL 20
  5342. +
  5343. +#define TEW_632BRP_CONFIG_ADDR 0x1f020000
  5344. +#define TEW_632BRP_CONFIG_SIZE 0x10000
  5345. +
  5346. +#ifdef CONFIG_MTD_PARTITIONS
  5347. +static struct mtd_partition tew_632brp_partitions[] = {
  5348. + {
  5349. + .name = "u-boot",
  5350. + .offset = 0,
  5351. + .size = 0x020000,
  5352. + .mask_flags = MTD_WRITEABLE,
  5353. + } , {
  5354. + .name = "config",
  5355. + .offset = 0x020000,
  5356. + .size = 0x010000,
  5357. + } , {
  5358. + .name = "kernel",
  5359. + .offset = 0x030000,
  5360. + .size = 0x0d0000,
  5361. + } , {
  5362. + .name = "rootfs",
  5363. + .offset = 0x100000,
  5364. + .size = 0x2f0000,
  5365. + } , {
  5366. + .name = "art",
  5367. + .offset = 0x3f0000,
  5368. + .size = 0x010000,
  5369. + .mask_flags = MTD_WRITEABLE,
  5370. + } , {
  5371. + .name = "firmware",
  5372. + .offset = 0x030000,
  5373. + .size = 0x3c0000,
  5374. + }
  5375. +};
  5376. +#endif /* CONFIG_MTD_PARTITIONS */
  5377. +
  5378. +static struct flash_platform_data tew_632brp_flash_data = {
  5379. +#ifdef CONFIG_MTD_PARTITIONS
  5380. + .parts = tew_632brp_partitions,
  5381. + .nr_parts = ARRAY_SIZE(tew_632brp_partitions),
  5382. +#endif
  5383. +};
  5384. +
  5385. +static struct gpio_led tew_632brp_leds_gpio[] __initdata = {
  5386. + {
  5387. + .name = "tew-632brp:green:status",
  5388. + .gpio = TEW_632BRP_GPIO_LED_STATUS,
  5389. + .active_low = 1,
  5390. + }, {
  5391. + .name = "tew-632brp:blue:wps",
  5392. + .gpio = TEW_632BRP_GPIO_LED_WPS,
  5393. + .active_low = 1,
  5394. + }, {
  5395. + .name = "tew-632brp:green:wlan",
  5396. + .gpio = TEW_632BRP_GPIO_LED_WLAN,
  5397. + .active_low = 1,
  5398. + }
  5399. +};
  5400. +
  5401. +static struct gpio_button tew_632brp_gpio_buttons[] __initdata = {
  5402. + {
  5403. + .desc = "reset",
  5404. + .type = EV_KEY,
  5405. + .code = KEY_RESTART,
  5406. + .threshold = 3,
  5407. + .gpio = TEW_632BRP_GPIO_BTN_RESET,
  5408. + }, {
  5409. + .desc = "wps",
  5410. + .type = EV_KEY,
  5411. + .code = KEY_WPS_BUTTON,
  5412. + .threshold = 3,
  5413. + .gpio = TEW_632BRP_GPIO_BTN_WPS,
  5414. + }
  5415. +};
  5416. +
  5417. +#define TEW_632BRP_LAN_PHYMASK BIT(0)
  5418. +#define TEW_632BRP_WAN_PHYMASK BIT(4)
  5419. +#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \
  5420. + TEW_632BRP_WAN_PHYMASK))
  5421. +
  5422. +static void __init tew_632brp_setup(void)
  5423. +{
  5424. + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR);
  5425. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5426. + u8 mac[6];
  5427. + u8 *wlan_mac = NULL;
  5428. +
  5429. + if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE,
  5430. + "lan_mac=", mac) == 0) {
  5431. + ar71xx_set_mac_base(mac);
  5432. + wlan_mac = mac;
  5433. + }
  5434. +
  5435. + ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK);
  5436. +
  5437. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5438. + ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK;
  5439. +
  5440. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5441. + ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK;
  5442. +
  5443. + ar71xx_add_device_eth(0);
  5444. + ar71xx_add_device_eth(1);
  5445. +
  5446. + ar71xx_add_device_m25p80(&tew_632brp_flash_data);
  5447. +
  5448. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio),
  5449. + tew_632brp_leds_gpio);
  5450. +
  5451. + ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL,
  5452. + ARRAY_SIZE(tew_632brp_gpio_buttons),
  5453. + tew_632brp_gpio_buttons);
  5454. +
  5455. + ar913x_add_device_wmac(eeprom, wlan_mac);
  5456. +}
  5457. +
  5458. +MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP",
  5459. + tew_632brp_setup);
  5460. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c
  5461. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100
  5462. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-05-27 14:36:51.000000000 +0200
  5463. @@ -0,0 +1,156 @@
  5464. +/*
  5465. + * TP-LINK TL-WR1043ND board support
  5466. + *
  5467. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5468. + *
  5469. + * This program is free software; you can redistribute it and/or modify it
  5470. + * under the terms of the GNU General Public License version 2 as published
  5471. + * by the Free Software Foundation.
  5472. + */
  5473. +
  5474. +#include <linux/mtd/mtd.h>
  5475. +#include <linux/mtd/partitions.h>
  5476. +#include <linux/platform_device.h>
  5477. +#include <linux/rtl8366rb.h>
  5478. +#include <asm/mach-ar71xx/ar71xx.h>
  5479. +
  5480. +#include "machtype.h"
  5481. +#include "devices.h"
  5482. +#include "dev-m25p80.h"
  5483. +#include "dev-ar913x-wmac.h"
  5484. +#include "dev-gpio-buttons.h"
  5485. +#include "dev-leds-gpio.h"
  5486. +#include "dev-usb.h"
  5487. +
  5488. +#define TL_WR1043ND_GPIO_LED_USB 1
  5489. +#define TL_WR1043ND_GPIO_LED_SYSTEM 2
  5490. +#define TL_WR1043ND_GPIO_LED_QSS 5
  5491. +#define TL_WR1043ND_GPIO_LED_WLAN 9
  5492. +
  5493. +#define TL_WR1043ND_GPIO_BTN_RESET 3
  5494. +#define TL_WR1043ND_GPIO_BTN_QSS 7
  5495. +
  5496. +#define TL_WR1043ND_GPIO_RTL8366_SDA 18
  5497. +#define TL_WR1043ND_GPIO_RTL8366_SCK 19
  5498. +
  5499. +#define TL_WR1043ND_BUTTONS_POLL_INTERVAL 20
  5500. +
  5501. +#ifdef CONFIG_MTD_PARTITIONS
  5502. +static struct mtd_partition tl_wr1043nd_partitions[] = {
  5503. + {
  5504. + .name = "u-boot",
  5505. + .offset = 0,
  5506. + .size = 0x020000,
  5507. + .mask_flags = MTD_WRITEABLE,
  5508. + } , {
  5509. + .name = "kernel",
  5510. + .offset = 0x020000,
  5511. + .size = 0x140000,
  5512. + } , {
  5513. + .name = "rootfs",
  5514. + .offset = 0x160000,
  5515. + .size = 0x690000,
  5516. + } , {
  5517. + .name = "art",
  5518. + .offset = 0x7f0000,
  5519. + .size = 0x010000,
  5520. + .mask_flags = MTD_WRITEABLE,
  5521. + } , {
  5522. + .name = "firmware",
  5523. + .offset = 0x020000,
  5524. + .size = 0x7d0000,
  5525. + }
  5526. +};
  5527. +#endif /* CONFIG_MTD_PARTITIONS */
  5528. +
  5529. +static struct flash_platform_data tl_wr1043nd_flash_data = {
  5530. +#ifdef CONFIG_MTD_PARTITIONS
  5531. + .parts = tl_wr1043nd_partitions,
  5532. + .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions),
  5533. +#endif
  5534. +};
  5535. +
  5536. +static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
  5537. + {
  5538. + .name = "tl-wr1043nd:green:usb",
  5539. + .gpio = TL_WR1043ND_GPIO_LED_USB,
  5540. + .active_low = 1,
  5541. + }, {
  5542. + .name = "tl-wr1043nd:green:system",
  5543. + .gpio = TL_WR1043ND_GPIO_LED_SYSTEM,
  5544. + .active_low = 1,
  5545. + }, {
  5546. + .name = "tl-wr1043nd:green:qss",
  5547. + .gpio = TL_WR1043ND_GPIO_LED_QSS,
  5548. + .active_low = 0,
  5549. + }, {
  5550. + .name = "tl-wr1043nd:green:wlan",
  5551. + .gpio = TL_WR1043ND_GPIO_LED_WLAN,
  5552. + .active_low = 1,
  5553. + }
  5554. +};
  5555. +
  5556. +static struct gpio_button tl_wr1043nd_gpio_buttons[] __initdata = {
  5557. + {
  5558. + .desc = "reset",
  5559. + .type = EV_KEY,
  5560. + .code = KEY_RESTART,
  5561. + .threshold = 3,
  5562. + .gpio = TL_WR1043ND_GPIO_BTN_RESET,
  5563. + .active_low = 1,
  5564. + }, {
  5565. + .desc = "qss",
  5566. + .type = EV_KEY,
  5567. + .code = KEY_WPS_BUTTON,
  5568. + .threshold = 3,
  5569. + .gpio = TL_WR1043ND_GPIO_BTN_QSS,
  5570. + .active_low = 1,
  5571. + }
  5572. +};
  5573. +
  5574. +static struct rtl8366rb_platform_data tl_wr1043nd_rtl8366rb_data = {
  5575. + .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA,
  5576. + .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK,
  5577. +};
  5578. +
  5579. +static struct platform_device tl_wr1043nd_rtl8366rb_device = {
  5580. + .name = RTL8366RB_DRIVER_NAME,
  5581. + .id = -1,
  5582. + .dev = {
  5583. + .platform_data = &tl_wr1043nd_rtl8366rb_data,
  5584. + }
  5585. +};
  5586. +
  5587. +static void __init tl_wr1043nd_setup(void)
  5588. +{
  5589. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5590. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5591. +
  5592. + ar71xx_set_mac_base(mac);
  5593. +
  5594. + ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev;
  5595. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5596. + ar71xx_eth0_data.speed = SPEED_1000;
  5597. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5598. + ar71xx_eth0_pll_data.pll_1000 = 0x1a000000;
  5599. +
  5600. + ar71xx_add_device_eth(0);
  5601. +
  5602. + ar71xx_add_device_usb();
  5603. +
  5604. + ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data);
  5605. +
  5606. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio),
  5607. + tl_wr1043nd_leds_gpio);
  5608. +
  5609. + platform_device_register(&tl_wr1043nd_rtl8366rb_device);
  5610. +
  5611. + ar71xx_add_device_gpio_buttons(-1, TL_WR1043ND_BUTTONS_POLL_INTERVAL,
  5612. + ARRAY_SIZE(tl_wr1043nd_gpio_buttons),
  5613. + tl_wr1043nd_gpio_buttons);
  5614. +
  5615. + ar913x_add_device_wmac(eeprom, mac);
  5616. +}
  5617. +
  5618. +MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND",
  5619. + tl_wr1043nd_setup);
  5620. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c
  5621. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100
  5622. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-05-27 14:36:51.000000000 +0200
  5623. @@ -0,0 +1,115 @@
  5624. +/*
  5625. + * TP-LINK TL-WR741ND board support
  5626. + *
  5627. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5628. + *
  5629. + * This program is free software; you can redistribute it and/or modify it
  5630. + * under the terms of the GNU General Public License version 2 as published
  5631. + * by the Free Software Foundation.
  5632. + */
  5633. +
  5634. +#include <linux/mtd/mtd.h>
  5635. +#include <linux/mtd/partitions.h>
  5636. +
  5637. +#include <asm/mach-ar71xx/ar71xx.h>
  5638. +
  5639. +#include "machtype.h"
  5640. +#include "devices.h"
  5641. +#include "dev-m25p80.h"
  5642. +#include "dev-ap91-eth.h"
  5643. +#include "dev-ap91-pci.h"
  5644. +#include "dev-gpio-buttons.h"
  5645. +#include "dev-leds-gpio.h"
  5646. +
  5647. +#define TL_WR741ND_GPIO_LED_QSS 0
  5648. +#define TL_WR741ND_GPIO_LED_SYSTEM 1
  5649. +
  5650. +#define TL_WR741ND_GPIO_BTN_RESET 11
  5651. +#define TL_WR741ND_GPIO_BTN_QSS 12
  5652. +
  5653. +#define TL_WR741ND_BUTTONS_POLL_INTERVAL 20
  5654. +
  5655. +#ifdef CONFIG_MTD_PARTITIONS
  5656. +static struct mtd_partition tl_wr741nd_partitions[] = {
  5657. + {
  5658. + .name = "u-boot",
  5659. + .offset = 0,
  5660. + .size = 0x020000,
  5661. + .mask_flags = MTD_WRITEABLE,
  5662. + } , {
  5663. + .name = "kernel",
  5664. + .offset = 0x020000,
  5665. + .size = 0x140000,
  5666. + } , {
  5667. + .name = "rootfs",
  5668. + .offset = 0x160000,
  5669. + .size = 0x290000,
  5670. + } , {
  5671. + .name = "art",
  5672. + .offset = 0x3f0000,
  5673. + .size = 0x010000,
  5674. + .mask_flags = MTD_WRITEABLE,
  5675. + } , {
  5676. + .name = "firmware",
  5677. + .offset = 0x020000,
  5678. + .size = 0x3d0000,
  5679. + }
  5680. +};
  5681. +#endif /* CONFIG_MTD_PARTITIONS */
  5682. +
  5683. +static struct flash_platform_data tl_wr741nd_flash_data = {
  5684. +#ifdef CONFIG_MTD_PARTITIONS
  5685. + .parts = tl_wr741nd_partitions,
  5686. + .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions),
  5687. +#endif
  5688. +};
  5689. +
  5690. +static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = {
  5691. + {
  5692. + .name = "tl-wr741nd:green:system",
  5693. + .gpio = TL_WR741ND_GPIO_LED_SYSTEM,
  5694. + .active_low = 1,
  5695. + }, {
  5696. + .name = "tl-wr741nd:green:qss",
  5697. + .gpio = TL_WR741ND_GPIO_LED_QSS,
  5698. + .active_low = 1,
  5699. + }
  5700. +};
  5701. +
  5702. +static struct gpio_button tl_wr741nd_gpio_buttons[] __initdata = {
  5703. + {
  5704. + .desc = "reset",
  5705. + .type = EV_KEY,
  5706. + .code = KEY_RESTART,
  5707. + .threshold = 3,
  5708. + .gpio = TL_WR741ND_GPIO_BTN_RESET,
  5709. + .active_low = 1,
  5710. + }, {
  5711. + .desc = "qss",
  5712. + .type = EV_KEY,
  5713. + .code = KEY_WPS_BUTTON,
  5714. + .threshold = 3,
  5715. + .gpio = TL_WR741ND_GPIO_BTN_QSS,
  5716. + .active_low = 1,
  5717. + }
  5718. +};
  5719. +
  5720. +static void __init tl_wr741nd_setup(void)
  5721. +{
  5722. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5723. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  5724. +
  5725. + ar71xx_add_device_m25p80(&tl_wr741nd_flash_data);
  5726. +
  5727. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio),
  5728. + tl_wr741nd_leds_gpio);
  5729. +
  5730. + ar71xx_add_device_gpio_buttons(-1, TL_WR741ND_BUTTONS_POLL_INTERVAL,
  5731. + ARRAY_SIZE(tl_wr741nd_gpio_buttons),
  5732. + tl_wr741nd_gpio_buttons);
  5733. +
  5734. + ap91_eth_init(mac, NULL);
  5735. + ap91_pci_init(ee, mac);
  5736. +}
  5737. +MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND",
  5738. + tl_wr741nd_setup);
  5739. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c
  5740. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100
  5741. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-05-27 14:36:51.000000000 +0200
  5742. @@ -0,0 +1,143 @@
  5743. +/*
  5744. + * TP-LINK TL-WR841N board support
  5745. + *
  5746. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5747. + *
  5748. + * This program is free software; you can redistribute it and/or modify it
  5749. + * under the terms of the GNU General Public License version 2 as published
  5750. + * by the Free Software Foundation.
  5751. + */
  5752. +
  5753. +#include <linux/mtd/mtd.h>
  5754. +#include <linux/mtd/partitions.h>
  5755. +
  5756. +#include <asm/mach-ar71xx/ar71xx.h>
  5757. +
  5758. +#include "machtype.h"
  5759. +#include "devices.h"
  5760. +#include "dev-dsa.h"
  5761. +#include "dev-m25p80.h"
  5762. +#include "dev-gpio-buttons.h"
  5763. +#include "dev-pb42-pci.h"
  5764. +#include "dev-leds-gpio.h"
  5765. +
  5766. +#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2
  5767. +#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4
  5768. +#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5
  5769. +
  5770. +#define TL_WR841ND_V1_GPIO_BTN_RESET 3
  5771. +#define TL_WR841ND_V1_GPIO_BTN_QSS 7
  5772. +
  5773. +#define TL_WR841ND_V1_BUTTONS_POLL_INTERVAL 20
  5774. +
  5775. +#ifdef CONFIG_MTD_PARTITIONS
  5776. +static struct mtd_partition tl_wr841n_v1_partitions[] = {
  5777. + {
  5778. + .name = "redboot",
  5779. + .offset = 0,
  5780. + .size = 0x020000,
  5781. + .mask_flags = MTD_WRITEABLE,
  5782. + } , {
  5783. + .name = "kernel",
  5784. + .offset = 0x020000,
  5785. + .size = 0x140000,
  5786. + } , {
  5787. + .name = "rootfs",
  5788. + .offset = 0x160000,
  5789. + .size = 0x280000,
  5790. + } , {
  5791. + .name = "config",
  5792. + .offset = 0x3e0000,
  5793. + .size = 0x020000,
  5794. + .mask_flags = MTD_WRITEABLE,
  5795. + } , {
  5796. + .name = "firmware",
  5797. + .offset = 0x020000,
  5798. + .size = 0x3c0000,
  5799. + }
  5800. +};
  5801. +#endif /* CONFIG_MTD_PARTITIONS */
  5802. +
  5803. +static struct flash_platform_data tl_wr841n_v1_flash_data = {
  5804. +#ifdef CONFIG_MTD_PARTITIONS
  5805. + .parts = tl_wr841n_v1_partitions,
  5806. + .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions),
  5807. +#endif
  5808. +};
  5809. +
  5810. +static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = {
  5811. + {
  5812. + .name = "tl-wr841n:green:system",
  5813. + .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM,
  5814. + .active_low = 1,
  5815. + }, {
  5816. + .name = "tl-wr841n:red:qss",
  5817. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED,
  5818. + }, {
  5819. + .name = "tl-wr841n:green:qss",
  5820. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN,
  5821. + }
  5822. +};
  5823. +
  5824. +static struct gpio_button tl_wr841n_v1_gpio_buttons[] __initdata = {
  5825. + {
  5826. + .desc = "reset",
  5827. + .type = EV_KEY,
  5828. + .code = KEY_RESTART,
  5829. + .threshold = 3,
  5830. + .gpio = TL_WR841ND_V1_GPIO_BTN_RESET,
  5831. + .active_low = 1,
  5832. + }, {
  5833. + .desc = "qss",
  5834. + .type = EV_KEY,
  5835. + .code = KEY_WPS_BUTTON,
  5836. + .threshold = 3,
  5837. + .gpio = TL_WR841ND_V1_GPIO_BTN_QSS,
  5838. + .active_low = 1,
  5839. + }
  5840. +};
  5841. +
  5842. +static struct dsa_chip_data tl_wr841n_v1_dsa_chip = {
  5843. + .port_names[0] = "wan",
  5844. + .port_names[1] = "lan1",
  5845. + .port_names[2] = "lan2",
  5846. + .port_names[3] = "lan3",
  5847. + .port_names[4] = "lan4",
  5848. + .port_names[5] = "cpu",
  5849. +};
  5850. +
  5851. +static struct dsa_platform_data tl_wr841n_v1_dsa_data = {
  5852. + .nr_chips = 1,
  5853. + .chip = &tl_wr841n_v1_dsa_chip,
  5854. +};
  5855. +
  5856. +static void __init tl_wr841n_v1_setup(void)
  5857. +{
  5858. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5859. +
  5860. + ar71xx_set_mac_base(mac);
  5861. +
  5862. + ar71xx_add_device_mdio(0x0);
  5863. +
  5864. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5865. + ar71xx_eth0_data.speed = SPEED_100;
  5866. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5867. +
  5868. + ar71xx_add_device_eth(0);
  5869. +
  5870. + ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data);
  5871. +
  5872. + ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data);
  5873. +
  5874. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio),
  5875. + tl_wr841n_v1_leds_gpio);
  5876. +
  5877. + ar71xx_add_device_gpio_buttons(-1, TL_WR841ND_V1_BUTTONS_POLL_INTERVAL,
  5878. + ARRAY_SIZE(tl_wr841n_v1_gpio_buttons),
  5879. + tl_wr841n_v1_gpio_buttons);
  5880. +
  5881. + pb42_pci_init();
  5882. +}
  5883. +
  5884. +MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1",
  5885. + tl_wr841n_v1_setup);
  5886. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c
  5887. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100
  5888. +++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-05-27 14:36:51.000000000 +0200
  5889. @@ -0,0 +1,142 @@
  5890. +/*
  5891. + * TP-LINK TL-WR941ND board support
  5892. + *
  5893. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5894. + *
  5895. + * This program is free software; you can redistribute it and/or modify it
  5896. + * under the terms of the GNU General Public License version 2 as published
  5897. + * by the Free Software Foundation.
  5898. + */
  5899. +
  5900. +#include <linux/mtd/mtd.h>
  5901. +#include <linux/mtd/partitions.h>
  5902. +
  5903. +#include <asm/mach-ar71xx/ar71xx.h>
  5904. +
  5905. +#include "machtype.h"
  5906. +#include "devices.h"
  5907. +#include "dev-dsa.h"
  5908. +#include "dev-m25p80.h"
  5909. +#include "dev-ar913x-wmac.h"
  5910. +#include "dev-gpio-buttons.h"
  5911. +#include "dev-leds-gpio.h"
  5912. +
  5913. +#define TL_WR941ND_GPIO_LED_SYSTEM 2
  5914. +#define TL_WR941ND_GPIO_LED_QSS_RED 4
  5915. +#define TL_WR941ND_GPIO_LED_QSS_GREEN 5
  5916. +
  5917. +#define TL_WR941ND_GPIO_BTN_RESET 3
  5918. +#define TL_WR941ND_GPIO_BTN_QSS 7
  5919. +
  5920. +#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20
  5921. +
  5922. +#ifdef CONFIG_MTD_PARTITIONS
  5923. +static struct mtd_partition tl_wr941nd_partitions[] = {
  5924. + {
  5925. + .name = "u-boot",
  5926. + .offset = 0,
  5927. + .size = 0x020000,
  5928. + .mask_flags = MTD_WRITEABLE,
  5929. + } , {
  5930. + .name = "kernel",
  5931. + .offset = 0x020000,
  5932. + .size = 0x140000,
  5933. + } , {
  5934. + .name = "rootfs",
  5935. + .offset = 0x160000,
  5936. + .size = 0x290000,
  5937. + } , {
  5938. + .name = "art",
  5939. + .offset = 0x3f0000,
  5940. + .size = 0x010000,
  5941. + .mask_flags = MTD_WRITEABLE,
  5942. + } , {
  5943. + .name = "firmware",
  5944. + .offset = 0x020000,
  5945. + .size = 0x3d0000,
  5946. + }
  5947. +};
  5948. +#endif /* CONFIG_MTD_PARTITIONS */
  5949. +
  5950. +static struct flash_platform_data tl_wr941nd_flash_data = {
  5951. +#ifdef CONFIG_MTD_PARTITIONS
  5952. + .parts = tl_wr941nd_partitions,
  5953. + .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions),
  5954. +#endif
  5955. +};
  5956. +
  5957. +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = {
  5958. + {
  5959. + .name = "tl-wr941nd:green:system",
  5960. + .gpio = TL_WR941ND_GPIO_LED_SYSTEM,
  5961. + .active_low = 1,
  5962. + }, {
  5963. + .name = "tl-wr941nd:red:qss",
  5964. + .gpio = TL_WR941ND_GPIO_LED_QSS_RED,
  5965. + }, {
  5966. + .name = "tl-wr941nd:green:qss",
  5967. + .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN,
  5968. + }
  5969. +};
  5970. +
  5971. +static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = {
  5972. + {
  5973. + .desc = "reset",
  5974. + .type = EV_KEY,
  5975. + .code = KEY_RESTART,
  5976. + .threshold = 3,
  5977. + .gpio = TL_WR941ND_GPIO_BTN_RESET,
  5978. + .active_low = 1,
  5979. + }, {
  5980. + .desc = "qss",
  5981. + .type = EV_KEY,
  5982. + .code = KEY_WPS_BUTTON,
  5983. + .threshold = 3,
  5984. + .gpio = TL_WR941ND_GPIO_BTN_QSS,
  5985. + .active_low = 1,
  5986. + }
  5987. +};
  5988. +
  5989. +static struct dsa_chip_data tl_wr941nd_dsa_chip = {
  5990. + .port_names[0] = "wan",
  5991. + .port_names[1] = "lan1",
  5992. + .port_names[2] = "lan2",
  5993. + .port_names[3] = "lan3",
  5994. + .port_names[4] = "lan4",
  5995. + .port_names[5] = "cpu",
  5996. +};
  5997. +
  5998. +static struct dsa_platform_data tl_wr941nd_dsa_data = {
  5999. + .nr_chips = 1,
  6000. + .chip = &tl_wr941nd_dsa_chip,
  6001. +};
  6002. +
  6003. +static void __init tl_wr941nd_setup(void)
  6004. +{
  6005. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  6006. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6007. +
  6008. + ar71xx_set_mac_base(mac);
  6009. +
  6010. + ar71xx_add_device_mdio(0x0);
  6011. +
  6012. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6013. + ar71xx_eth0_data.speed = SPEED_100;
  6014. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6015. +
  6016. + ar71xx_add_device_eth(0);
  6017. + ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data);
  6018. +
  6019. + ar71xx_add_device_m25p80(&tl_wr941nd_flash_data);
  6020. +
  6021. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio),
  6022. + tl_wr941nd_leds_gpio);
  6023. +
  6024. + ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL,
  6025. + ARRAY_SIZE(tl_wr941nd_gpio_buttons),
  6026. + tl_wr941nd_gpio_buttons);
  6027. + ar913x_add_device_wmac(eeprom, mac);
  6028. +}
  6029. +
  6030. +MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND",
  6031. + tl_wr941nd_setup);
  6032. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c
  6033. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100
  6034. +++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-05-27 14:36:51.000000000 +0200
  6035. @@ -0,0 +1,281 @@
  6036. +/*
  6037. + * Ubiquiti RouterStation support
  6038. + *
  6039. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6040. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6041. + * Copyright (C) 2008 Ubiquiti <support@ubnt.com>
  6042. + *
  6043. + * This program is free software; you can redistribute it and/or modify it
  6044. + * under the terms of the GNU General Public License version 2 as published
  6045. + * by the Free Software Foundation.
  6046. + */
  6047. +
  6048. +#include <asm/mach-ar71xx/ar71xx.h>
  6049. +
  6050. +#include "machtype.h"
  6051. +#include "devices.h"
  6052. +#include "dev-m25p80.h"
  6053. +#include "dev-ap91-pci.h"
  6054. +#include "dev-gpio-buttons.h"
  6055. +#include "dev-pb42-pci.h"
  6056. +#include "dev-leds-gpio.h"
  6057. +#include "dev-usb.h"
  6058. +
  6059. +#define UBNT_RS_GPIO_LED_RF 2
  6060. +#define UBNT_RS_GPIO_SW4 8
  6061. +
  6062. +#define UBNT_LS_SR71_GPIO_LED_D25 0
  6063. +#define UBNT_LS_SR71_GPIO_LED_D26 1
  6064. +#define UBNT_LS_SR71_GPIO_LED_D24 2
  6065. +#define UBNT_LS_SR71_GPIO_LED_D23 4
  6066. +#define UBNT_LS_SR71_GPIO_LED_D22 5
  6067. +#define UBNT_LS_SR71_GPIO_LED_D27 6
  6068. +#define UBNT_LS_SR71_GPIO_LED_D28 7
  6069. +
  6070. +#define UBNT_M_GPIO_LED_L1 0
  6071. +#define UBNT_M_GPIO_LED_L2 1
  6072. +#define UBNT_M_GPIO_LED_L3 11
  6073. +#define UBNT_M_GPIO_LED_L4 7
  6074. +#define UBNT_M_GPIO_BTN_RESET 12
  6075. +
  6076. +#define UBNT_BUTTONS_POLL_INTERVAL 20
  6077. +
  6078. +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = {
  6079. + {
  6080. + .name = "ubnt:green:rf",
  6081. + .gpio = UBNT_RS_GPIO_LED_RF,
  6082. + .active_low = 0,
  6083. + }
  6084. +};
  6085. +
  6086. +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = {
  6087. + {
  6088. + .name = "ubnt:green:d22",
  6089. + .gpio = UBNT_LS_SR71_GPIO_LED_D22,
  6090. + .active_low = 0,
  6091. + }, {
  6092. + .name = "ubnt:green:d23",
  6093. + .gpio = UBNT_LS_SR71_GPIO_LED_D23,
  6094. + .active_low = 0,
  6095. + }, {
  6096. + .name = "ubnt:green:d24",
  6097. + .gpio = UBNT_LS_SR71_GPIO_LED_D24,
  6098. + .active_low = 0,
  6099. + }, {
  6100. + .name = "ubnt:red:d25",
  6101. + .gpio = UBNT_LS_SR71_GPIO_LED_D25,
  6102. + .active_low = 0,
  6103. + }, {
  6104. + .name = "ubnt:red:d26",
  6105. + .gpio = UBNT_LS_SR71_GPIO_LED_D26,
  6106. + .active_low = 0,
  6107. + }, {
  6108. + .name = "ubnt:green:d27",
  6109. + .gpio = UBNT_LS_SR71_GPIO_LED_D27,
  6110. + .active_low = 0,
  6111. + }, {
  6112. + .name = "ubnt:green:d28",
  6113. + .gpio = UBNT_LS_SR71_GPIO_LED_D28,
  6114. + .active_low = 0,
  6115. + }
  6116. +};
  6117. +
  6118. +static struct gpio_led ubnt_m_leds_gpio[] __initdata = {
  6119. + {
  6120. + .name = "ubnt:red:link1",
  6121. + .gpio = UBNT_M_GPIO_LED_L1,
  6122. + .active_low = 0,
  6123. + }, {
  6124. + .name = "ubnt:orange:link2",
  6125. + .gpio = UBNT_M_GPIO_LED_L2,
  6126. + .active_low = 0,
  6127. + }, {
  6128. + .name = "ubnt:green:link3",
  6129. + .gpio = UBNT_M_GPIO_LED_L3,
  6130. + .active_low = 0,
  6131. + }, {
  6132. + .name = "ubnt:green:link4",
  6133. + .gpio = UBNT_M_GPIO_LED_L4,
  6134. + .active_low = 0,
  6135. + }
  6136. +};
  6137. +
  6138. +static struct gpio_button ubnt_gpio_buttons[] __initdata = {
  6139. + {
  6140. + .desc = "sw4",
  6141. + .type = EV_KEY,
  6142. + .code = KEY_RESTART,
  6143. + .threshold = 3,
  6144. + .gpio = UBNT_RS_GPIO_SW4,
  6145. + .active_low = 1,
  6146. + }
  6147. +};
  6148. +
  6149. +static struct gpio_button ubnt_m_gpio_buttons[] __initdata = {
  6150. + {
  6151. + .desc = "reset",
  6152. + .type = EV_KEY,
  6153. + .code = KEY_RESTART,
  6154. + .threshold = 3,
  6155. + .gpio = UBNT_M_GPIO_BTN_RESET,
  6156. + .active_low = 1,
  6157. + }
  6158. +};
  6159. +
  6160. +static void __init ubnt_generic_setup(void)
  6161. +{
  6162. + ar71xx_add_device_m25p80(NULL);
  6163. +
  6164. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6165. + ARRAY_SIZE(ubnt_gpio_buttons),
  6166. + ubnt_gpio_buttons);
  6167. +
  6168. + pb42_pci_init();
  6169. +}
  6170. +
  6171. +#define UBNT_RS_WAN_PHYMASK (1 << 20)
  6172. +#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19))
  6173. +
  6174. +static void __init ubnt_rs_setup(void)
  6175. +{
  6176. + ubnt_generic_setup();
  6177. +
  6178. + ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK));
  6179. +
  6180. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6181. + ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK;
  6182. +
  6183. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6184. + ar71xx_eth1_data.speed = SPEED_100;
  6185. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6186. +
  6187. + ar71xx_add_device_eth(0);
  6188. + ar71xx_add_device_eth(1);
  6189. +
  6190. + ar71xx_add_device_usb();
  6191. +
  6192. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6193. + ubnt_rs_leds_gpio);
  6194. +}
  6195. +
  6196. +MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation",
  6197. + ubnt_rs_setup);
  6198. +
  6199. +MIPS_MACHINE(AR71XX_MACH_UBNT_AR71XX, "Ubiquiti AR71xx-based board",
  6200. + "Ubiquiti RouterStation", ubnt_rs_setup);
  6201. +
  6202. +#define UBNT_RSPRO_WAN_PHYMASK (1 << 4)
  6203. +#define UBNT_RSPRO_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
  6204. +
  6205. +static void __init ubnt_rspro_setup(void)
  6206. +{
  6207. + ubnt_generic_setup();
  6208. +
  6209. + ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | UBNT_RSPRO_LAN_PHYMASK));
  6210. +
  6211. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6212. + ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK;
  6213. +
  6214. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6215. + ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK;
  6216. + ar71xx_eth1_data.speed = SPEED_1000;
  6217. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6218. +
  6219. + ar71xx_add_device_eth(0);
  6220. + ar71xx_add_device_eth(1);
  6221. +
  6222. + ar71xx_add_device_usb();
  6223. +
  6224. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6225. + ubnt_rs_leds_gpio);
  6226. +}
  6227. +
  6228. +MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro",
  6229. + ubnt_rspro_setup);
  6230. +
  6231. +static void __init ubnt_lsx_setup(void)
  6232. +{
  6233. + ubnt_generic_setup();
  6234. +}
  6235. +
  6236. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup);
  6237. +
  6238. +#define UBNT_LSSR71_PHY_MASK (1 << 1)
  6239. +
  6240. +static void __init ubnt_lssr71_setup(void)
  6241. +{
  6242. + ubnt_generic_setup();
  6243. +
  6244. + ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK);
  6245. +
  6246. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6247. + ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK;
  6248. +
  6249. + ar71xx_add_device_eth(0);
  6250. +
  6251. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio),
  6252. + ubnt_ls_sr71_leds_gpio);
  6253. +}
  6254. +
  6255. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71",
  6256. + ubnt_lssr71_setup);
  6257. +
  6258. +static void __init ubnt_m_setup(void)
  6259. +{
  6260. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  6261. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  6262. +
  6263. + ar71xx_set_mac_base(mac);
  6264. +
  6265. + ar71xx_add_device_m25p80(NULL);
  6266. +
  6267. + ar71xx_add_device_mdio(~0);
  6268. +
  6269. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6270. + ar71xx_eth0_data.speed = SPEED_100;
  6271. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6272. + ar71xx_eth0_data.fifo_cfg1 = 0x0010ffff;
  6273. + ar71xx_eth0_data.fifo_cfg2 = 0x015500aa;
  6274. + ar71xx_eth0_data.fifo_cfg3 = 0x01f00140;
  6275. +
  6276. + ar71xx_add_device_eth(0);
  6277. +
  6278. + ap91_pci_init(ee, NULL);
  6279. +
  6280. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio),
  6281. + ubnt_m_leds_gpio);
  6282. +
  6283. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6284. + ARRAY_SIZE(ubnt_m_gpio_buttons),
  6285. + ubnt_m_gpio_buttons);
  6286. +}
  6287. +
  6288. +static void __init ubnt_rocket_m_setup(void)
  6289. +{
  6290. + ubnt_m_setup();
  6291. + ar71xx_add_device_usb();
  6292. +}
  6293. +
  6294. +MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M",
  6295. + ubnt_m_setup);
  6296. +MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M",
  6297. + ubnt_rocket_m_setup);
  6298. +
  6299. +/* TODO detect the second ethernet port and use one
  6300. + init function for all Ubiquiti MIMO series products */
  6301. +static void __init ubnt_nano_m_setup(void)
  6302. +{
  6303. + ubnt_m_setup();
  6304. +
  6305. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6306. + ar71xx_eth1_data.speed = SPEED_1000;
  6307. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6308. + ar71xx_eth1_data.fifo_cfg1 = 0x0010ffff;
  6309. + ar71xx_eth1_data.fifo_cfg2 = 0x015500aa;
  6310. + ar71xx_eth1_data.fifo_cfg3 = 0x01f00140;
  6311. +
  6312. + ar71xx_add_device_eth(1);
  6313. +}
  6314. +
  6315. +MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M",
  6316. + ubnt_nano_m_setup);
  6317. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c
  6318. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100
  6319. +++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-05-27 14:36:51.000000000 +0200
  6320. @@ -0,0 +1,209 @@
  6321. +/*
  6322. + * Netgear WNDR3700 board support
  6323. + *
  6324. + * Copyright (C) 2009 Marco Porsch
  6325. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6326. + *
  6327. + * This program is free software; you can redistribute it and/or modify it
  6328. + * under the terms of the GNU General Public License version 2 as published
  6329. + * by the Free Software Foundation.
  6330. + */
  6331. +
  6332. +#include <linux/platform_device.h>
  6333. +#include <linux/mtd/mtd.h>
  6334. +#include <linux/mtd/partitions.h>
  6335. +#include <linux/delay.h>
  6336. +#include <linux/rtl8366s.h>
  6337. +
  6338. +#include <asm/mach-ar71xx/ar71xx.h>
  6339. +
  6340. +#include "machtype.h"
  6341. +#include "devices.h"
  6342. +#include "dev-m25p80.h"
  6343. +#include "dev-ap94-pci.h"
  6344. +#include "dev-gpio-buttons.h"
  6345. +#include "dev-leds-gpio.h"
  6346. +#include "dev-usb.h"
  6347. +
  6348. +#define WNDR3700_GPIO_LED_WPS_ORANGE 0
  6349. +#define WNDR3700_GPIO_LED_POWER_ORANGE 1
  6350. +#define WNDR3700_GPIO_LED_POWER_GREEN 2
  6351. +#define WNDR3700_GPIO_LED_WPS_GREEN 4
  6352. +#define WNDR3700_GPIO_LED_WAN_GREEN 6
  6353. +
  6354. +#define WNDR3700_GPIO_BTN_WPS 3
  6355. +#define WNDR3700_GPIO_BTN_RESET 8
  6356. +#define WNDR3700_GPIO_BTN_WIFI 11
  6357. +
  6358. +#define WNDR3700_GPIO_RTL8366_SDA 5
  6359. +#define WNDR3700_GPIO_RTL8366_SCK 7
  6360. +
  6361. +#define WNDR3700_BUTTONS_POLL_INTERVAL 20
  6362. +
  6363. +#define WNDR3700_WMAC0_MAC_OFFSET 0
  6364. +#define WNDR3700_WMAC1_MAC_OFFSET 0xc
  6365. +#define WNDR3700_CALDATA0_OFFSET 0x1000
  6366. +#define WNDR3700_CALDATA1_OFFSET 0x5000
  6367. +
  6368. +#ifdef CONFIG_MTD_PARTITIONS
  6369. +static struct mtd_partition wndr3700_partitions[] = {
  6370. + {
  6371. + .name = "uboot",
  6372. + .offset = 0,
  6373. + .size = 0x050000,
  6374. + .mask_flags = MTD_WRITEABLE,
  6375. + } , {
  6376. + .name = "env",
  6377. + .offset = 0x050000,
  6378. + .size = 0x020000,
  6379. + .mask_flags = MTD_WRITEABLE,
  6380. + } , {
  6381. + .name = "rootfs",
  6382. + .offset = 0x070000,
  6383. + .size = 0x720000,
  6384. + } , {
  6385. + .name = "config",
  6386. + .offset = 0x790000,
  6387. + .size = 0x010000,
  6388. + .mask_flags = MTD_WRITEABLE,
  6389. + } , {
  6390. + .name = "config_bak",
  6391. + .offset = 0x7a0000,
  6392. + .size = 0x010000,
  6393. + .mask_flags = MTD_WRITEABLE,
  6394. + } , {
  6395. + .name = "pot",
  6396. + .offset = 0x7b0000,
  6397. + .size = 0x010000,
  6398. + .mask_flags = MTD_WRITEABLE,
  6399. + } , {
  6400. + .name = "traffic_meter",
  6401. + .offset = 0x7c0000,
  6402. + .size = 0x010000,
  6403. + .mask_flags = MTD_WRITEABLE,
  6404. + } , {
  6405. + .name = "language",
  6406. + .offset = 0x7d0000,
  6407. + .size = 0x020000,
  6408. + .mask_flags = MTD_WRITEABLE,
  6409. + } , {
  6410. + .name = "caldata",
  6411. + .offset = 0x7f0000,
  6412. + .size = 0x010000,
  6413. + .mask_flags = MTD_WRITEABLE,
  6414. + }
  6415. +};
  6416. +#endif /* CONFIG_MTD_PARTITIONS */
  6417. +
  6418. +static struct flash_platform_data wndr3700_flash_data = {
  6419. +#ifdef CONFIG_MTD_PARTITIONS
  6420. + .parts = wndr3700_partitions,
  6421. + .nr_parts = ARRAY_SIZE(wndr3700_partitions),
  6422. +#endif
  6423. +};
  6424. +
  6425. +static struct gpio_led wndr3700_leds_gpio[] __initdata = {
  6426. + {
  6427. + .name = "wndr3700:green:power",
  6428. + .gpio = WNDR3700_GPIO_LED_POWER_GREEN,
  6429. + .active_low = 1,
  6430. + }, {
  6431. + .name = "wndr3700:orange:power",
  6432. + .gpio = WNDR3700_GPIO_LED_POWER_ORANGE,
  6433. + .active_low = 1,
  6434. + }, {
  6435. + .name = "wndr3700:green:wps",
  6436. + .gpio = WNDR3700_GPIO_LED_WPS_GREEN,
  6437. + .active_low = 1,
  6438. + }, {
  6439. + .name = "wndr3700:orange:wps",
  6440. + .gpio = WNDR3700_GPIO_LED_WPS_ORANGE,
  6441. + .active_low = 1,
  6442. + }, {
  6443. + .name = "wndr3700:green:wan",
  6444. + .gpio = WNDR3700_GPIO_LED_WAN_GREEN,
  6445. + .active_low = 1,
  6446. + }
  6447. +};
  6448. +
  6449. +static struct gpio_button wndr3700_gpio_buttons[] __initdata = {
  6450. + {
  6451. + .desc = "reset",
  6452. + .type = EV_KEY,
  6453. + .code = KEY_RESTART,
  6454. + .threshold = 3,
  6455. + .gpio = WNDR3700_GPIO_BTN_RESET,
  6456. + .active_low = 1,
  6457. + }, {
  6458. + .desc = "wps",
  6459. + .type = EV_KEY,
  6460. + .code = KEY_WPS_BUTTON,
  6461. + .threshold = 3,
  6462. + .gpio = WNDR3700_GPIO_BTN_WPS,
  6463. + .active_low = 1,
  6464. + } , {
  6465. + .desc = "wifi",
  6466. + .type = EV_KEY,
  6467. + .code = BTN_2,
  6468. + .threshold = 3,
  6469. + .gpio = WNDR3700_GPIO_BTN_WIFI,
  6470. + .active_low = 1,
  6471. + }
  6472. +};
  6473. +
  6474. +static struct rtl8366s_platform_data wndr3700_rtl8366s_data = {
  6475. + .gpio_sda = WNDR3700_GPIO_RTL8366_SDA,
  6476. + .gpio_sck = WNDR3700_GPIO_RTL8366_SCK,
  6477. +};
  6478. +
  6479. +static struct platform_device wndr3700_rtl8366s_device = {
  6480. + .name = RTL8366S_DRIVER_NAME,
  6481. + .id = -1,
  6482. + .dev = {
  6483. + .platform_data = &wndr3700_rtl8366s_data,
  6484. + }
  6485. +};
  6486. +
  6487. +static void __init wndr3700_setup(void)
  6488. +{
  6489. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  6490. +
  6491. + ar71xx_set_mac_base(art);
  6492. +
  6493. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  6494. + ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6495. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6496. + ar71xx_eth0_data.speed = SPEED_1000;
  6497. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6498. +
  6499. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  6500. + ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6501. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6502. + ar71xx_eth1_data.phy_mask = 0x10;
  6503. +
  6504. + ar71xx_add_device_eth(0);
  6505. + ar71xx_add_device_eth(1);
  6506. +
  6507. + ar71xx_add_device_usb();
  6508. +
  6509. + ar71xx_add_device_m25p80(&wndr3700_flash_data);
  6510. +
  6511. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio),
  6512. + wndr3700_leds_gpio);
  6513. +
  6514. + ar71xx_add_device_gpio_buttons(-1, WNDR3700_BUTTONS_POLL_INTERVAL,
  6515. + ARRAY_SIZE(wndr3700_gpio_buttons),
  6516. + wndr3700_gpio_buttons);
  6517. +
  6518. + platform_device_register(&wndr3700_rtl8366s_device);
  6519. + platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0);
  6520. +
  6521. + ap94_pci_enable_quirk_wndr3700();
  6522. + ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET,
  6523. + art + WNDR3700_WMAC0_MAC_OFFSET,
  6524. + art + WNDR3700_CALDATA1_OFFSET,
  6525. + art + WNDR3700_WMAC1_MAC_OFFSET);
  6526. +}
  6527. +
  6528. +MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700",
  6529. + wndr3700_setup);
  6530. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c
  6531. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100
  6532. +++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-05-27 14:36:51.000000000 +0200
  6533. @@ -0,0 +1,148 @@
  6534. +/*
  6535. + * NETGEAR WNR2000 board support
  6536. + *
  6537. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6538. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6539. + * Copyright (C) 2008-2009 Andy Boyett <agb@openwrt.org>
  6540. + *
  6541. + * This program is free software; you can redistribute it and/or modify it
  6542. + * under the terms of the GNU General Public License version 2 as published
  6543. + * by the Free Software Foundation.
  6544. + */
  6545. +
  6546. +#include <linux/mtd/mtd.h>
  6547. +#include <linux/mtd/partitions.h>
  6548. +
  6549. +#include <asm/mach-ar71xx/ar71xx.h>
  6550. +
  6551. +#include "machtype.h"
  6552. +#include "devices.h"
  6553. +#include "dev-m25p80.h"
  6554. +#include "dev-ar913x-wmac.h"
  6555. +#include "dev-gpio-buttons.h"
  6556. +#include "dev-leds-gpio.h"
  6557. +
  6558. +#define WNR2000_GPIO_LED_PWR_GREEN 14
  6559. +#define WNR2000_GPIO_LED_PWR_AMBER 7
  6560. +#define WNR2000_GPIO_LED_WPS 4
  6561. +#define WNR2000_GPIO_LED_WLAN 6
  6562. +#define WNR2000_GPIO_BTN_RESET 21
  6563. +#define WNR2000_GPIO_BTN_WPS 8
  6564. +
  6565. +#define WNR2000_BUTTONS_POLL_INTERVAL 20
  6566. +
  6567. +#ifdef CONFIG_MTD_PARTITIONS
  6568. +static struct mtd_partition wnr2000_partitions[] = {
  6569. + {
  6570. + .name = "u-boot",
  6571. + .offset = 0,
  6572. + .size = 0x040000,
  6573. + .mask_flags = MTD_WRITEABLE,
  6574. + } , {
  6575. + .name = "u-boot-env",
  6576. + .offset = 0x040000,
  6577. + .size = 0x010000,
  6578. + } , {
  6579. + .name = "rootfs",
  6580. + .offset = 0x050000,
  6581. + .size = 0x240000,
  6582. + } , {
  6583. + .name = "user-config",
  6584. + .offset = 0x290000,
  6585. + .size = 0x010000,
  6586. + } , {
  6587. + .name = "uImage",
  6588. + .offset = 0x2a0000,
  6589. + .size = 0x120000,
  6590. + } , {
  6591. + .name = "language_table",
  6592. + .offset = 0x3c0000,
  6593. + .size = 0x020000,
  6594. + } , {
  6595. + .name = "rootfs_checksum",
  6596. + .offset = 0x3e0000,
  6597. + .size = 0x010000,
  6598. + } , {
  6599. + .name = "art",
  6600. + .offset = 0x3f0000,
  6601. + .size = 0x010000,
  6602. + .mask_flags = MTD_WRITEABLE,
  6603. + }
  6604. +};
  6605. +#endif /* CONFIG_MTD_PARTITIONS */
  6606. +
  6607. +static struct flash_platform_data wnr2000_flash_data = {
  6608. +#ifdef CONFIG_MTD_PARTITIONS
  6609. + .parts = wnr2000_partitions,
  6610. + .nr_parts = ARRAY_SIZE(wnr2000_partitions),
  6611. +#endif
  6612. +};
  6613. +
  6614. +static struct gpio_led wnr2000_leds_gpio[] __initdata = {
  6615. + {
  6616. + .name = "wnr2000:green:power",
  6617. + .gpio = WNR2000_GPIO_LED_PWR_GREEN,
  6618. + .active_low = 1,
  6619. + }, {
  6620. + .name = "wnr2000:amber:power",
  6621. + .gpio = WNR2000_GPIO_LED_PWR_AMBER,
  6622. + .active_low = 1,
  6623. + }, {
  6624. + .name = "wnr2000:green:wps",
  6625. + .gpio = WNR2000_GPIO_LED_WPS,
  6626. + .active_low = 1,
  6627. + }, {
  6628. + .name = "wnr2000:blue:wlan",
  6629. + .gpio = WNR2000_GPIO_LED_WLAN,
  6630. + .active_low = 1,
  6631. + }
  6632. +};
  6633. +
  6634. +static struct gpio_button wnr2000_gpio_buttons[] __initdata = {
  6635. + {
  6636. + .desc = "reset",
  6637. + .type = EV_KEY,
  6638. + .code = KEY_RESTART,
  6639. + .threshold = 3,
  6640. + .gpio = WNR2000_GPIO_BTN_RESET,
  6641. + }, {
  6642. + .desc = "wps",
  6643. + .type = EV_KEY,
  6644. + .code = KEY_WPS_BUTTON,
  6645. + .threshold = 3,
  6646. + .gpio = WNR2000_GPIO_BTN_WPS,
  6647. + }
  6648. +};
  6649. +
  6650. +static void __init wnr2000_setup(void)
  6651. +{
  6652. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6653. +
  6654. + ar71xx_set_mac_base(eeprom);
  6655. + ar71xx_add_device_mdio(0x0);
  6656. +
  6657. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6658. + ar71xx_eth0_data.speed = SPEED_100;
  6659. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6660. + ar71xx_eth0_data.has_ar8216 = 1;
  6661. +
  6662. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6663. + ar71xx_eth1_data.phy_mask = 0x10;
  6664. +
  6665. + ar71xx_add_device_eth(0);
  6666. + ar71xx_add_device_eth(1);
  6667. +
  6668. + ar71xx_add_device_m25p80(&wnr2000_flash_data);
  6669. +
  6670. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio),
  6671. + wnr2000_leds_gpio);
  6672. +
  6673. + ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL,
  6674. + ARRAY_SIZE(wnr2000_gpio_buttons),
  6675. + wnr2000_gpio_buttons);
  6676. +
  6677. +
  6678. + ar913x_add_device_wmac(eeprom, NULL);
  6679. +}
  6680. +
  6681. +MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup);
  6682. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c
  6683. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100
  6684. +++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-05-27 14:36:51.000000000 +0200
  6685. @@ -0,0 +1,99 @@
  6686. +/*
  6687. + * Compex WP543/WPJ543 board support
  6688. + *
  6689. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6690. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6691. + *
  6692. + * This program is free software; you can redistribute it and/or modify it
  6693. + * under the terms of the GNU General Public License version 2 as published
  6694. + * by the Free Software Foundation.
  6695. + */
  6696. +
  6697. +#include <linux/mtd/mtd.h>
  6698. +#include <linux/mtd/partitions.h>
  6699. +
  6700. +#include <asm/mach-ar71xx/ar71xx.h>
  6701. +
  6702. +#include "machtype.h"
  6703. +#include "devices.h"
  6704. +#include "dev-m25p80.h"
  6705. +#include "dev-pb42-pci.h"
  6706. +#include "dev-gpio-buttons.h"
  6707. +#include "dev-leds-gpio.h"
  6708. +#include "dev-usb.h"
  6709. +
  6710. +#define WP543_GPIO_SW6 2
  6711. +#define WP543_GPIO_LED_1 3
  6712. +#define WP543_GPIO_LED_2 4
  6713. +#define WP543_GPIO_LED_WLAN 5
  6714. +#define WP543_GPIO_LED_CONN 6
  6715. +#define WP543_GPIO_LED_DIAG 7
  6716. +#define WP543_GPIO_SW4 8
  6717. +
  6718. +#define WP543_BUTTONS_POLL_INTERVAL 20
  6719. +
  6720. +static struct gpio_led wp543_leds_gpio[] __initdata = {
  6721. + {
  6722. + .name = "wp543:green:led1",
  6723. + .gpio = WP543_GPIO_LED_1,
  6724. + .active_low = 1,
  6725. + }, {
  6726. + .name = "wp543:green:led2",
  6727. + .gpio = WP543_GPIO_LED_2,
  6728. + .active_low = 1,
  6729. + }, {
  6730. + .name = "wp543:green:wlan",
  6731. + .gpio = WP543_GPIO_LED_WLAN,
  6732. + .active_low = 1,
  6733. + }, {
  6734. + .name = "wp543:green:conn",
  6735. + .gpio = WP543_GPIO_LED_CONN,
  6736. + .active_low = 1,
  6737. + }, {
  6738. + .name = "wp543:green:diag",
  6739. + .gpio = WP543_GPIO_LED_DIAG,
  6740. + .active_low = 1,
  6741. + }
  6742. +};
  6743. +
  6744. +static struct gpio_button wp543_gpio_buttons[] __initdata = {
  6745. + {
  6746. + .desc = "sw6",
  6747. + .type = EV_KEY,
  6748. + .code = BTN_0,
  6749. + .threshold = 3,
  6750. + .gpio = WP543_GPIO_SW6,
  6751. + }, {
  6752. + .desc = "sw4",
  6753. + .type = EV_KEY,
  6754. + .code = BTN_1,
  6755. + .threshold = 3,
  6756. + .gpio = WP543_GPIO_SW4,
  6757. + }
  6758. +};
  6759. +
  6760. +static void __init wp543_setup(void)
  6761. +{
  6762. + ar71xx_add_device_m25p80(NULL);
  6763. +
  6764. + ar71xx_add_device_mdio(0xfffffff7);
  6765. +
  6766. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6767. + ar71xx_eth0_data.phy_mask = 0x08;
  6768. + ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC |
  6769. + RESET_MODULE_GE0_PHY;
  6770. + ar71xx_add_device_eth(0);
  6771. +
  6772. + ar71xx_add_device_usb();
  6773. +
  6774. + pb42_pci_init();
  6775. +
  6776. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio),
  6777. + wp543_leds_gpio);
  6778. +
  6779. + ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL,
  6780. + ARRAY_SIZE(wp543_gpio_buttons),
  6781. + wp543_gpio_buttons);
  6782. +}
  6783. +
  6784. +MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup);
  6785. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c
  6786. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100
  6787. +++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-05-27 14:36:51.000000000 +0200
  6788. @@ -0,0 +1,158 @@
  6789. +/*
  6790. + * Linksys WRT160NL board support
  6791. + *
  6792. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  6793. + *
  6794. + * This program is free software; you can redistribute it and/or modify it
  6795. + * under the terms of the GNU General Public License version 2 as published
  6796. + * by the Free Software Foundation.
  6797. + */
  6798. +
  6799. +#include <linux/mtd/mtd.h>
  6800. +#include <linux/mtd/partitions.h>
  6801. +
  6802. +#include <asm/mach-ar71xx/ar71xx.h>
  6803. +
  6804. +#include "machtype.h"
  6805. +#include "devices.h"
  6806. +#include "dev-m25p80.h"
  6807. +#include "dev-ar913x-wmac.h"
  6808. +#include "dev-gpio-buttons.h"
  6809. +#include "dev-leds-gpio.h"
  6810. +#include "dev-usb.h"
  6811. +#include "nvram.h"
  6812. +
  6813. +#define WRT160NL_GPIO_LED_POWER 14
  6814. +#define WRT160NL_GPIO_LED_WPS_AMBER 9
  6815. +#define WRT160NL_GPIO_LED_WPS_BLUE 8
  6816. +#define WRT160NL_GPIO_LED_WLAN 6
  6817. +
  6818. +#define WRT160NL_GPIO_BTN_WPS 7
  6819. +#define WRT160NL_GPIO_BTN_RESET 21
  6820. +
  6821. +#define WRT160NL_BUTTONS_POLL_INTERVAL 20
  6822. +
  6823. +#define WRT160NL_NVRAM_ADDR 0x1f7e0000
  6824. +#define WRT160NL_NVRAM_SIZE 0x10000
  6825. +
  6826. +#ifdef CONFIG_MTD_PARTITIONS
  6827. +static struct mtd_partition wrt160nl_partitions[] = {
  6828. + {
  6829. + .name = "u-boot",
  6830. + .offset = 0,
  6831. + .size = 0x040000,
  6832. + .mask_flags = MTD_WRITEABLE,
  6833. + } , {
  6834. + .name = "kernel",
  6835. + .offset = 0x040000,
  6836. + .size = 0x0e0000,
  6837. + } , {
  6838. + .name = "filesytem",
  6839. + .offset = 0x120000,
  6840. + .size = 0x6c0000,
  6841. + } , {
  6842. + .name = "nvram",
  6843. + .offset = 0x7e0000,
  6844. + .size = 0x010000,
  6845. + .mask_flags = MTD_WRITEABLE,
  6846. + } , {
  6847. + .name = "ART",
  6848. + .offset = 0x7f0000,
  6849. + .size = 0x010000,
  6850. + .mask_flags = MTD_WRITEABLE,
  6851. + } , {
  6852. + .name = "firmware",
  6853. + .offset = 0x040000,
  6854. + .size = 0x7a0000,
  6855. + }
  6856. +};
  6857. +#endif /* CONFIG_MTD_PARTITIONS */
  6858. +
  6859. +static struct flash_platform_data wrt160nl_flash_data = {
  6860. +#ifdef CONFIG_MTD_PARTITIONS
  6861. + .parts = wrt160nl_partitions,
  6862. + .nr_parts = ARRAY_SIZE(wrt160nl_partitions),
  6863. +#endif
  6864. +};
  6865. +
  6866. +static struct gpio_led wrt160nl_leds_gpio[] __initdata = {
  6867. + {
  6868. + .name = "wrt160nl:blue:power",
  6869. + .gpio = WRT160NL_GPIO_LED_POWER,
  6870. + .active_low = 1,
  6871. + .default_trigger = "default-on",
  6872. + }, {
  6873. + .name = "wrt160nl:amber:wps",
  6874. + .gpio = WRT160NL_GPIO_LED_WPS_AMBER,
  6875. + .active_low = 1,
  6876. + }, {
  6877. + .name = "wrt160nl:blue:wps",
  6878. + .gpio = WRT160NL_GPIO_LED_WPS_BLUE,
  6879. + .active_low = 1,
  6880. + }, {
  6881. + .name = "wrt160nl:blue:wlan",
  6882. + .gpio = WRT160NL_GPIO_LED_WLAN,
  6883. + .active_low = 1,
  6884. + }
  6885. +};
  6886. +
  6887. +static struct gpio_button wrt160nl_gpio_buttons[] __initdata = {
  6888. + {
  6889. + .desc = "reset",
  6890. + .type = EV_KEY,
  6891. + .code = KEY_RESTART,
  6892. + .threshold = 3,
  6893. + .gpio = WRT160NL_GPIO_BTN_RESET,
  6894. + .active_low = 1,
  6895. + }, {
  6896. + .desc = "wps",
  6897. + .type = EV_KEY,
  6898. + .code = KEY_WPS_BUTTON,
  6899. + .threshold = 3,
  6900. + .gpio = WRT160NL_GPIO_BTN_WPS,
  6901. + .active_low = 1,
  6902. + }
  6903. +};
  6904. +
  6905. +static void __init wrt160nl_setup(void)
  6906. +{
  6907. + const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR);
  6908. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6909. + u8 mac[6];
  6910. +
  6911. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6912. + "lan_hwaddr=", mac) == 0)
  6913. + ar71xx_set_mac_base(mac);
  6914. +
  6915. + ar71xx_add_device_mdio(0x0);
  6916. +
  6917. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6918. + ar71xx_eth0_data.phy_mask = 0x01;
  6919. +
  6920. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6921. + ar71xx_eth1_data.phy_mask = 0x10;
  6922. +
  6923. + ar71xx_add_device_eth(0);
  6924. + ar71xx_add_device_eth(1);
  6925. +
  6926. + ar71xx_add_device_m25p80(&wrt160nl_flash_data);
  6927. +
  6928. + ar71xx_add_device_usb();
  6929. +
  6930. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6931. + "wl0_hwaddr=", mac) == 0)
  6932. + ar913x_add_device_wmac(eeprom, mac);
  6933. + else
  6934. + ar913x_add_device_wmac(eeprom, NULL);
  6935. +
  6936. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio),
  6937. + wrt160nl_leds_gpio);
  6938. +
  6939. + ar71xx_add_device_gpio_buttons(-1, WRT160NL_BUTTONS_POLL_INTERVAL,
  6940. + ARRAY_SIZE(wrt160nl_gpio_buttons),
  6941. + wrt160nl_gpio_buttons);
  6942. +
  6943. +}
  6944. +
  6945. +MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL",
  6946. + wrt160nl_setup);
  6947. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c
  6948. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100
  6949. +++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-05-27 14:36:51.000000000 +0200
  6950. @@ -0,0 +1,168 @@
  6951. +/*
  6952. + * Linksys WRT400N board support
  6953. + *
  6954. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6955. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  6956. + *
  6957. + * This program is free software; you can redistribute it and/or modify it
  6958. + * under the terms of the GNU General Public License version 2 as published
  6959. + * by the Free Software Foundation.
  6960. + */
  6961. +
  6962. +#include <linux/mtd/mtd.h>
  6963. +#include <linux/mtd/partitions.h>
  6964. +
  6965. +#include <asm/mach-ar71xx/ar71xx.h>
  6966. +
  6967. +#include "machtype.h"
  6968. +#include "devices.h"
  6969. +#include "dev-ap94-pci.h"
  6970. +#include "dev-m25p80.h"
  6971. +#include "dev-gpio-buttons.h"
  6972. +#include "dev-leds-gpio.h"
  6973. +
  6974. +#define WRT400N_GPIO_LED_ORANGE 5
  6975. +#define WRT400N_GPIO_LED_GREEN 4
  6976. +#define WRT400N_GPIO_LED_POWER 1
  6977. +#define WRT400N_GPIO_LED_WLAN 0
  6978. +
  6979. +#define WRT400N_GPIO_BTN_RESET 8
  6980. +#define WRT400N_GPIO_BTN_WLSEC 3
  6981. +
  6982. +#define WRT400N_BUTTONS_POLL_INTERVAL 20
  6983. +
  6984. +#define WRT400N_MAC_ADDR_OFFSET 0x120c
  6985. +#define WRT400N_CALDATA0_OFFSET 0x1000
  6986. +#define WRT400N_CALDATA1_OFFSET 0x5000
  6987. +
  6988. +#ifdef CONFIG_MTD_PARTITIONS
  6989. +static struct mtd_partition wrt400n_partitions[] = {
  6990. + {
  6991. + .name = "uboot",
  6992. + .offset = 0,
  6993. + .size = 0x030000,
  6994. + .mask_flags = MTD_WRITEABLE,
  6995. + } , {
  6996. + .name = "env",
  6997. + .offset = 0x030000,
  6998. + .size = 0x010000,
  6999. + .mask_flags = MTD_WRITEABLE,
  7000. + } , {
  7001. + .name = "linux",
  7002. + .offset = 0x040000,
  7003. + .size = 0x140000,
  7004. + } , {
  7005. + .name = "rootfs",
  7006. + .offset = 0x180000,
  7007. + .size = 0x630000,
  7008. + } , {
  7009. + .name = "nvram",
  7010. + .offset = 0x7b0000,
  7011. + .size = 0x010000,
  7012. + .mask_flags = MTD_WRITEABLE,
  7013. + } , {
  7014. + .name = "factory",
  7015. + .offset = 0x7c0000,
  7016. + .size = 0x010000,
  7017. + .mask_flags = MTD_WRITEABLE,
  7018. + } , {
  7019. + .name = "language",
  7020. + .offset = 0x7d0000,
  7021. + .size = 0x020000,
  7022. + .mask_flags = MTD_WRITEABLE,
  7023. + } , {
  7024. + .name = "caldata",
  7025. + .offset = 0x7f0000,
  7026. + .size = 0x010000,
  7027. + .mask_flags = MTD_WRITEABLE,
  7028. + } , {
  7029. + .name = "firmware",
  7030. + .offset = 0x040000,
  7031. + .size = 0x770000,
  7032. + }
  7033. +};
  7034. +#endif /* CONFIG_MTD_PARTITIONS */
  7035. +
  7036. +static struct flash_platform_data wrt400n_flash_data = {
  7037. +#ifdef CONFIG_MTD_PARTITIONS
  7038. + .parts = wrt400n_partitions,
  7039. + .nr_parts = ARRAY_SIZE(wrt400n_partitions),
  7040. +#endif
  7041. +};
  7042. +
  7043. +static struct gpio_led wrt400n_leds_gpio[] __initdata = {
  7044. + {
  7045. + .name = "wrt400n:green:status",
  7046. + .gpio = WRT400N_GPIO_LED_GREEN,
  7047. + .active_low = 1,
  7048. + }, {
  7049. + .name = "wrt400n:amber:aoss",
  7050. + .gpio = WRT400N_GPIO_LED_ORANGE,
  7051. + .active_low = 1,
  7052. + }, {
  7053. + .name = "wrt400n:green:wlan",
  7054. + .gpio = WRT400N_GPIO_LED_WLAN,
  7055. + .active_low = 1,
  7056. + }, {
  7057. + .name = "wrt400n:green:power",
  7058. + .gpio = WRT400N_GPIO_LED_POWER,
  7059. + .active_low = 1,
  7060. + }
  7061. +};
  7062. +
  7063. +static struct gpio_button wrt400n_gpio_buttons[] __initdata = {
  7064. + {
  7065. + .desc = "reset",
  7066. + .type = EV_KEY,
  7067. + .code = KEY_RESTART,
  7068. + .threshold = 3,
  7069. + .gpio = WRT400N_GPIO_BTN_RESET,
  7070. + .active_low = 1,
  7071. + } , {
  7072. + .desc = "wlsec",
  7073. + .type = EV_KEY,
  7074. + .code = KEY_WPS_BUTTON,
  7075. + .threshold = 3,
  7076. + .gpio = WRT400N_GPIO_BTN_WLSEC,
  7077. + .active_low = 1,
  7078. + }
  7079. +};
  7080. +
  7081. +static void __init wrt400n_setup(void)
  7082. +{
  7083. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  7084. + u8 mac[6];
  7085. + int i;
  7086. +
  7087. + memcpy(mac, art + WRT400N_MAC_ADDR_OFFSET, 6);
  7088. + for (i = 5; i >= 3; i--)
  7089. + if (++mac[i] != 0x00) break;
  7090. +
  7091. + ar71xx_set_mac_base(mac);
  7092. +
  7093. + ar71xx_add_device_mdio(0x0);
  7094. +
  7095. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7096. + ar71xx_eth0_data.speed = SPEED_100;
  7097. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7098. +
  7099. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7100. + ar71xx_eth1_data.phy_mask = 0x10;
  7101. +
  7102. + ar71xx_add_device_eth(0);
  7103. + ar71xx_add_device_eth(1);
  7104. +
  7105. + ar71xx_add_device_m25p80(&wrt400n_flash_data);
  7106. +
  7107. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio),
  7108. + wrt400n_leds_gpio);
  7109. +
  7110. + ar71xx_add_device_gpio_buttons(-1, WRT400N_BUTTONS_POLL_INTERVAL,
  7111. + ARRAY_SIZE(wrt400n_gpio_buttons),
  7112. + wrt400n_gpio_buttons);
  7113. +
  7114. + ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL,
  7115. + art + WRT400N_CALDATA1_OFFSET, NULL);
  7116. +}
  7117. +
  7118. +MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup);
  7119. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c
  7120. --- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100
  7121. +++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-05-27 14:36:51.000000000 +0200
  7122. @@ -0,0 +1,265 @@
  7123. +/*
  7124. + * Buffalo WZR-HP-G300NH board support
  7125. + *
  7126. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  7127. + *
  7128. + * This program is free software; you can redistribute it and/or modify it
  7129. + * under the terms of the GNU General Public License version 2 as published
  7130. + * by the Free Software Foundation.
  7131. + */
  7132. +
  7133. +#include <linux/platform_device.h>
  7134. +#include <linux/mtd/mtd.h>
  7135. +#include <linux/mtd/partitions.h>
  7136. +#include <linux/nxp_74hc153.h>
  7137. +#include <linux/rtl8366s.h>
  7138. +
  7139. +#include <asm/mips_machine.h>
  7140. +#include <asm/mach-ar71xx/ar71xx.h>
  7141. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  7142. +
  7143. +#include "machtype.h"
  7144. +#include "devices.h"
  7145. +#include "dev-ar913x-wmac.h"
  7146. +#include "dev-gpio-buttons.h"
  7147. +#include "dev-leds-gpio.h"
  7148. +#include "dev-usb.h"
  7149. +
  7150. +#define WZRHPG300NH_GPIO_LED_USB 0
  7151. +#define WZRHPG300NH_GPIO_LED_DIAG 1
  7152. +#define WZRHPG300NH_GPIO_LED_WIRELESS 6
  7153. +#define WZRHPG300NH_GPIO_LED_SECURITY 17
  7154. +#define WZRHPG300NH_GPIO_LED_ROUTER 18
  7155. +
  7156. +#define WZRHPG300NH_GPIO_RTL8366_SDA 19
  7157. +#define WZRHPG300NH_GPIO_RTL8366_SCK 20
  7158. +
  7159. +#define WZRHPG300NH_GPIO_74HC153_S0 9
  7160. +#define WZRHPG300NH_GPIO_74HC153_S1 11
  7161. +#define WZRHPG300NH_GPIO_74HC153_1Y 12
  7162. +#define WZRHPG300NH_GPIO_74HC153_2Y 14
  7163. +
  7164. +#define WZRHPG300NH_GPIO_EXP_BASE 32
  7165. +#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0)
  7166. +#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1)
  7167. +#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2)
  7168. +#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3)
  7169. +#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5)
  7170. +#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6)
  7171. +#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7)
  7172. +
  7173. +#define WZRHPG300NH_BUTTONS_POLL_INTERVAL 20
  7174. +
  7175. +#define WZRHPG300NH_MAC_OFFSET 0x20c
  7176. +
  7177. +#ifdef CONFIG_MTD_PARTITIONS
  7178. +static struct mtd_partition wzrhpg300nh_flash_partitions[] = {
  7179. + {
  7180. + .name = "u-boot",
  7181. + .offset = 0,
  7182. + .size = 0x0040000,
  7183. + .mask_flags = MTD_WRITEABLE,
  7184. + }, {
  7185. + .name = "u-boot-env",
  7186. + .offset = 0x0040000,
  7187. + .size = 0x0020000,
  7188. + .mask_flags = MTD_WRITEABLE,
  7189. + }, {
  7190. + .name = "kernel",
  7191. + .offset = 0x0060000,
  7192. + .size = 0x0100000,
  7193. + }, {
  7194. + .name = "rootfs",
  7195. + .offset = 0x0160000,
  7196. + .size = 0x1e60000,
  7197. + }, {
  7198. + .name = "user_property",
  7199. + .offset = 0x1fc0000,
  7200. + .size = 0x0020000,
  7201. + .mask_flags = MTD_WRITEABLE,
  7202. + }, {
  7203. + .name = "art",
  7204. + .offset = 0x1fe0000,
  7205. + .size = 0x0020000,
  7206. + .mask_flags = MTD_WRITEABLE,
  7207. + }, {
  7208. + .name = "firmware",
  7209. + .offset = 0x0060000,
  7210. + .size = 0x1f60000,
  7211. + }
  7212. +};
  7213. +#endif /* CONFIG_MTD_PARTITIONS */
  7214. +
  7215. +static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = {
  7216. + .width = 2,
  7217. +#ifdef CONFIG_MTD_PARTITIONS
  7218. + .parts = wzrhpg300nh_flash_partitions,
  7219. + .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions),
  7220. +#endif
  7221. +};
  7222. +
  7223. +#define WZRHPG300NH_FLASH_BASE 0x1e000000
  7224. +#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024)
  7225. +
  7226. +static struct resource wzrhpg300nh_flash_resources[] = {
  7227. + [0] = {
  7228. + .start = WZRHPG300NH_FLASH_BASE,
  7229. + .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1,
  7230. + .flags = IORESOURCE_MEM,
  7231. + },
  7232. +};
  7233. +
  7234. +static struct platform_device wzrhpg300nh_flash_device = {
  7235. + .name = "ar91xx-flash",
  7236. + .id = -1,
  7237. + .resource = wzrhpg300nh_flash_resources,
  7238. + .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources),
  7239. + .dev = {
  7240. + .platform_data = &wzrhpg300nh_flash_data,
  7241. + }
  7242. +};
  7243. +
  7244. +static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = {
  7245. + {
  7246. + .name = "wzr-hp-g300nh:orange:security",
  7247. + .gpio = WZRHPG300NH_GPIO_LED_SECURITY,
  7248. + .active_low = 1,
  7249. + }, {
  7250. + .name = "wzr-hp-g300nh:green:wireless",
  7251. + .gpio = WZRHPG300NH_GPIO_LED_WIRELESS,
  7252. + .active_low = 1,
  7253. + }, {
  7254. + .name = "wzr-hp-g300nh:green:router",
  7255. + .gpio = WZRHPG300NH_GPIO_LED_ROUTER,
  7256. + .active_low = 1,
  7257. + }, {
  7258. + .name = "wzr-hp-g300nh:red:diag",
  7259. + .gpio = WZRHPG300NH_GPIO_LED_DIAG,
  7260. + .active_low = 1,
  7261. + }, {
  7262. + .name = "wzr-hp-g300nh:blue:usb",
  7263. + .gpio = WZRHPG300NH_GPIO_LED_USB,
  7264. + .active_low = 1,
  7265. + }
  7266. +};
  7267. +
  7268. +static struct gpio_button wzrhpg300nh_gpio_buttons[] __initdata = {
  7269. + {
  7270. + .desc = "reset",
  7271. + .type = EV_KEY,
  7272. + .code = KEY_RESTART,
  7273. + .threshold = 3,
  7274. + .gpio = WZRHPG300NH_GPIO_BTN_RESET,
  7275. + .active_low = 1,
  7276. + }, {
  7277. + .desc = "aoss",
  7278. + .type = EV_KEY,
  7279. + .code = KEY_WPS_BUTTON,
  7280. + .threshold = 3,
  7281. + .gpio = WZRHPG300NH_GPIO_BTN_AOSS,
  7282. + .active_low = 1,
  7283. + }, {
  7284. + .desc = "usb",
  7285. + .type = EV_KEY,
  7286. + .code = BTN_2,
  7287. + .threshold = 3,
  7288. + .gpio = WZRHPG300NH_GPIO_BTN_USB,
  7289. + .active_low = 1,
  7290. + }, {
  7291. + .desc = "qos_on",
  7292. + .type = EV_KEY,
  7293. + .code = BTN_3,
  7294. + .threshold = 3,
  7295. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON,
  7296. + .active_low = 0,
  7297. + }, {
  7298. + .desc = "qos_off",
  7299. + .type = EV_KEY,
  7300. + .code = BTN_4,
  7301. + .threshold = 3,
  7302. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF,
  7303. + .active_low = 0,
  7304. + }, {
  7305. + .desc = "router_on",
  7306. + .type = EV_KEY,
  7307. + .code = BTN_5,
  7308. + .threshold = 3,
  7309. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON,
  7310. + .active_low = 0,
  7311. + }, {
  7312. + .desc = "router_auto",
  7313. + .type = EV_KEY,
  7314. + .code = BTN_6,
  7315. + .threshold = 3,
  7316. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO,
  7317. + .active_low = 0,
  7318. + }
  7319. +};
  7320. +
  7321. +static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = {
  7322. + .gpio_base = WZRHPG300NH_GPIO_EXP_BASE,
  7323. + .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0,
  7324. + .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1,
  7325. + .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y,
  7326. + .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y,
  7327. +};
  7328. +
  7329. +static struct platform_device wzrhpg300nh_74hc153_device = {
  7330. + .name = NXP_74HC153_DRIVER_NAME,
  7331. + .id = -1,
  7332. + .dev = {
  7333. + .platform_data = &wzrhpg300nh_74hc153_data,
  7334. + }
  7335. +};
  7336. +
  7337. +static struct rtl8366s_platform_data wzrhpg300nh_rtl8366s_data = {
  7338. + .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA,
  7339. + .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK,
  7340. +};
  7341. +
  7342. +static struct platform_device wzrhpg300nh_rtl8366s_device = {
  7343. + .name = RTL8366S_DRIVER_NAME,
  7344. + .id = -1,
  7345. + .dev = {
  7346. + .platform_data = &wzrhpg300nh_rtl8366s_data,
  7347. + }
  7348. +};
  7349. +
  7350. +static void __init wzrhpg300nh_setup(void)
  7351. +{
  7352. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7353. +
  7354. + ar71xx_set_mac_base(eeprom + WZRHPG300NH_MAC_OFFSET);
  7355. +
  7356. + ar71xx_eth0_pll_data.pll_1000 = 0x1e000100;
  7357. + ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7358. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7359. + ar71xx_eth0_data.speed = SPEED_1000;
  7360. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7361. +
  7362. + ar71xx_eth1_pll_data.pll_1000 = 0x1e000100;
  7363. + ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7364. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7365. + ar71xx_eth1_data.phy_mask = 0x10;
  7366. +
  7367. + ar71xx_add_device_eth(0);
  7368. + ar71xx_add_device_eth(1);
  7369. +
  7370. + ar71xx_add_device_usb();
  7371. + ar913x_add_device_wmac(eeprom, NULL);
  7372. +
  7373. + platform_device_register(&wzrhpg300nh_74hc153_device);
  7374. + platform_device_register(&wzrhpg300nh_flash_device);
  7375. + platform_device_register(&wzrhpg300nh_rtl8366s_device);
  7376. +
  7377. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio),
  7378. + wzrhpg300nh_leds_gpio);
  7379. +
  7380. + ar71xx_add_device_gpio_buttons(-1, WZRHPG300NH_BUTTONS_POLL_INTERVAL,
  7381. + ARRAY_SIZE(wzrhpg300nh_gpio_buttons),
  7382. + wzrhpg300nh_gpio_buttons);
  7383. +
  7384. +}
  7385. +
  7386. +MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH",
  7387. + "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup);
  7388. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h
  7389. --- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100
  7390. +++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-05-27 14:36:51.000000000 +0200
  7391. @@ -0,0 +1,60 @@
  7392. +/*
  7393. + * Atheros AR71xx machine type definitions
  7394. + *
  7395. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  7396. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7397. + *
  7398. + * This program is free software; you can redistribute it and/or modify it
  7399. + * under the terms of the GNU General Public License version 2 as published
  7400. + * by the Free Software Foundation.
  7401. + */
  7402. +
  7403. +#ifndef _AR71XX_MACHTYPE_H
  7404. +#define _AR71XX_MACHTYPE_H
  7405. +
  7406. +#include <asm/mips_machine.h>
  7407. +
  7408. +enum ar71xx_mach_type {
  7409. + AR71XX_MACH_GENERIC = 0,
  7410. + AR71XX_MACH_AP81, /* Atheros AP81 */
  7411. + AR71XX_MACH_AP83, /* Atheros AP83 */
  7412. + AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */
  7413. + AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */
  7414. + AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */
  7415. + AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */
  7416. + AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */
  7417. + AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */
  7418. + AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */
  7419. + AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */
  7420. + AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */
  7421. + AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */
  7422. + AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */
  7423. + AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */
  7424. + AR71XX_MACH_PB42, /* Atheros PB42 */
  7425. + AR71XX_MACH_PB44, /* Atheros PB44 */
  7426. + AR71XX_MACH_PB92, /* Atheros PB92 */
  7427. + AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */
  7428. + AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */
  7429. + AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */
  7430. + AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */
  7431. + AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */
  7432. + AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */
  7433. + AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */
  7434. + AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */
  7435. + AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */
  7436. + AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */
  7437. + AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */
  7438. + AR71XX_MACH_UBNT_AR71XX, /* Ubiquiti AR71xx-based board */
  7439. + AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
  7440. + AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */
  7441. + AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
  7442. + AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
  7443. + AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */
  7444. + AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */
  7445. + AR71XX_MACH_WP543, /* Compex WP543 */
  7446. + AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */
  7447. + AR71XX_MACH_WRT400N, /* Linksys WRT400N */
  7448. + AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */
  7449. +};
  7450. +
  7451. +#endif /* _AR71XX_MACHTYPE_H */
  7452. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c
  7453. --- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
  7454. +++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-05-27 14:36:51.000000000 +0200
  7455. @@ -0,0 +1,75 @@
  7456. +/*
  7457. + * Atheros AR71xx minimal nvram support
  7458. + *
  7459. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7460. + *
  7461. + * This program is free software; you can redistribute it and/or modify it
  7462. + * under the terms of the GNU General Public License version 2 as published
  7463. + * by the Free Software Foundation.
  7464. + */
  7465. +
  7466. +#include <linux/kernel.h>
  7467. +#include <linux/vmalloc.h>
  7468. +#include <linux/errno.h>
  7469. +#include <linux/init.h>
  7470. +#include <linux/string.h>
  7471. +
  7472. +#include "nvram.h"
  7473. +
  7474. +char *nvram_find_var(const char *name, const char *buf, unsigned buf_len)
  7475. +{
  7476. + unsigned len = strlen(name);
  7477. + char *cur, *last;
  7478. +
  7479. + if (buf_len == 0 || len == 0)
  7480. + return NULL;
  7481. +
  7482. + if (buf_len < len)
  7483. + return NULL;
  7484. +
  7485. + if (len == 1)
  7486. + return memchr(buf, (int) *name, buf_len);
  7487. +
  7488. + last = (char *) buf + buf_len - len;
  7489. + for (cur = (char *) buf; cur <= last; cur++)
  7490. + if (cur[0] == name[0] && memcmp(cur, name, len) == 0)
  7491. + return cur + len;
  7492. +
  7493. + return NULL;
  7494. +}
  7495. +
  7496. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7497. + const char *name, char *mac)
  7498. +{
  7499. + char *buf;
  7500. + char *mac_str;
  7501. + int ret;
  7502. + int t;
  7503. +
  7504. + buf = vmalloc(nvram_len);
  7505. + if (!buf)
  7506. + return -ENOMEM;
  7507. +
  7508. + memcpy(buf, nvram, nvram_len);
  7509. + buf[nvram_len - 1] = '\0';
  7510. +
  7511. + mac_str = nvram_find_var(name, buf, nvram_len);
  7512. + if (!mac_str) {
  7513. + ret = -EINVAL;
  7514. + goto free;
  7515. + }
  7516. +
  7517. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  7518. + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
  7519. +
  7520. + if (t != 6) {
  7521. + ret = -EINVAL;
  7522. + goto free;
  7523. + }
  7524. +
  7525. + ret = 0;
  7526. +
  7527. + free:
  7528. + vfree(buf);
  7529. + return ret;
  7530. +}
  7531. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h
  7532. --- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100
  7533. +++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-05-27 14:36:51.000000000 +0200
  7534. @@ -0,0 +1,19 @@
  7535. +/*
  7536. + * Atheros AR71xx minimal nvram support
  7537. + *
  7538. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7539. + *
  7540. + * This program is free software; you can redistribute it and/or modify it
  7541. + * under the terms of the GNU General Public License version 2 as published
  7542. + * by the Free Software Foundation.
  7543. + */
  7544. +
  7545. +#ifndef _AR71XX_NVRAM_H
  7546. +#define _AR71XX_NVRAM_H
  7547. +
  7548. +char *nvram_find_var(const char *name, const char *buf,
  7549. + unsigned buf_len) __init;
  7550. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7551. + const char *name, char *mac) __init;
  7552. +
  7553. +#endif /* _AR71XX_NVRAM_H */
  7554. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c
  7555. --- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100
  7556. +++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-05-27 14:36:51.000000000 +0200
  7557. @@ -0,0 +1,93 @@
  7558. +/*
  7559. + * Atheros AR71xx PCI setup code
  7560. + *
  7561. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7562. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7563. + *
  7564. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7565. + *
  7566. + * This program is free software; you can redistribute it and/or modify it
  7567. + * under the terms of the GNU General Public License version 2 as published
  7568. + * by the Free Software Foundation.
  7569. + */
  7570. +
  7571. +#include <linux/kernel.h>
  7572. +
  7573. +#include <asm/traps.h>
  7574. +
  7575. +#include <asm/mach-ar71xx/ar71xx.h>
  7576. +#include <asm/mach-ar71xx/pci.h>
  7577. +
  7578. +unsigned ar71xx_pci_nr_irqs __initdata;
  7579. +struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  7580. +
  7581. +int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  7582. +
  7583. +static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
  7584. +{
  7585. + int err = 0;
  7586. +
  7587. + err = ar71xx_pci_be_handler(is_fixup);
  7588. +
  7589. + return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  7590. +}
  7591. +
  7592. +int pcibios_plat_dev_init(struct pci_dev *dev)
  7593. +{
  7594. + if (ar71xx_pci_plat_dev_init)
  7595. + return ar71xx_pci_plat_dev_init(dev);
  7596. +
  7597. + return 0;
  7598. +}
  7599. +
  7600. +int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
  7601. +{
  7602. + int ret = 0;
  7603. +
  7604. + switch (ar71xx_soc) {
  7605. + case AR71XX_SOC_AR7130:
  7606. + case AR71XX_SOC_AR7141:
  7607. + case AR71XX_SOC_AR7161:
  7608. + ret = ar71xx_pcibios_map_irq(dev, slot, pin);
  7609. + break;
  7610. +
  7611. + case AR71XX_SOC_AR7240:
  7612. + case AR71XX_SOC_AR7241:
  7613. + case AR71XX_SOC_AR7242:
  7614. + ret = ar724x_pcibios_map_irq(dev, slot, pin);
  7615. + break;
  7616. +
  7617. + default:
  7618. + break;
  7619. + }
  7620. +
  7621. + return ret;
  7622. +}
  7623. +
  7624. +int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  7625. +{
  7626. + int ret = 0;
  7627. +
  7628. + switch (ar71xx_soc) {
  7629. + case AR71XX_SOC_AR7130:
  7630. + case AR71XX_SOC_AR7141:
  7631. + case AR71XX_SOC_AR7161:
  7632. + board_be_handler = ar71xx_be_handler;
  7633. + ret = ar71xx_pcibios_init();
  7634. + break;
  7635. +
  7636. + case AR71XX_SOC_AR7240:
  7637. + case AR71XX_SOC_AR7241:
  7638. + case AR71XX_SOC_AR7242:
  7639. + ret = ar724x_pcibios_init();
  7640. + break;
  7641. +
  7642. + default:
  7643. + return 0;
  7644. + }
  7645. +
  7646. + ar71xx_pci_nr_irqs = nr_irqs;
  7647. + ar71xx_pci_irq_map = map;
  7648. +
  7649. + return ret;
  7650. +}
  7651. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c
  7652. --- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100
  7653. +++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-05-27 14:36:51.000000000 +0200
  7654. @@ -0,0 +1,105 @@
  7655. +/*
  7656. + * Atheros AR71xx SoC specific prom routines
  7657. + *
  7658. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7659. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7660. + *
  7661. + * This program is free software; you can redistribute it and/or modify it
  7662. + * under the terms of the GNU General Public License version 2 as published
  7663. + * by the Free Software Foundation.
  7664. + */
  7665. +
  7666. +#include <linux/kernel.h>
  7667. +#include <linux/init.h>
  7668. +#include <linux/io.h>
  7669. +#include <linux/string.h>
  7670. +
  7671. +#include <asm/bootinfo.h>
  7672. +#include <asm/addrspace.h>
  7673. +
  7674. +#include <asm/mach-ar71xx/ar71xx.h>
  7675. +
  7676. +static inline int is_valid_ram_addr(void *addr)
  7677. +{
  7678. + if (((u32) addr > KSEG0) &&
  7679. + ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX)))
  7680. + return 1;
  7681. +
  7682. + if (((u32) addr > KSEG1) &&
  7683. + ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX)))
  7684. + return 1;
  7685. +
  7686. + return 0;
  7687. +}
  7688. +
  7689. +static void __init ar71xx_prom_append_cmdline(const char *name,
  7690. + const char *value)
  7691. +{
  7692. + char buf[COMMAND_LINE_SIZE];
  7693. +
  7694. + snprintf(buf, sizeof(buf), " %s=%s", name, value);
  7695. + strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline));
  7696. +}
  7697. +
  7698. +static void __init ar71xx_prom_find_env(char **envp, const char *name)
  7699. +{
  7700. + int len = strlen(name);
  7701. + char **p;
  7702. +
  7703. + if (!is_valid_ram_addr(envp))
  7704. + return;
  7705. +
  7706. + for (p = envp; is_valid_ram_addr(*p); p++) {
  7707. + if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') {
  7708. + ar71xx_prom_append_cmdline(name, *p + len + 1);
  7709. + break;
  7710. + }
  7711. +
  7712. + /* RedBoot env comes in pointer pairs - key, value */
  7713. + if (strncmp(name, *p, len) == 0 && (*p)[len] == 0)
  7714. + if (is_valid_ram_addr(*(++p))) {
  7715. + ar71xx_prom_append_cmdline(name, *p);
  7716. + break;
  7717. + }
  7718. + }
  7719. +}
  7720. +
  7721. +static int inline ar71xx_use__image_cmdline(void) { return 0; }
  7722. +
  7723. +static __init void ar71xx_prom_init_cmdline(int argc, char **argv)
  7724. +{
  7725. + int i;
  7726. +
  7727. + if (ar71xx_use__image_cmdline())
  7728. + return;
  7729. +
  7730. + if (!is_valid_ram_addr(argv))
  7731. + return;
  7732. +
  7733. + for (i = 0; i < argc; i++)
  7734. + if (is_valid_ram_addr(argv[i])) {
  7735. + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
  7736. + strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
  7737. + }
  7738. +}
  7739. +
  7740. +void __init prom_init(void)
  7741. +{
  7742. + char **envp;
  7743. +
  7744. + printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, "
  7745. + "fw_arg2=%08x, fw_arg3=%08x\n",
  7746. + (unsigned int)fw_arg0, (unsigned int)fw_arg1,
  7747. + (unsigned int)fw_arg2, (unsigned int)fw_arg3);
  7748. +
  7749. +
  7750. + ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
  7751. +
  7752. + envp = (char **)fw_arg2;
  7753. + ar71xx_prom_find_env(envp, "board");
  7754. +}
  7755. +
  7756. +void __init prom_free_prom_memory(void)
  7757. +{
  7758. + /* We do not have to prom memory to free */
  7759. +}
  7760. diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c
  7761. --- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100
  7762. +++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-05-27 14:36:51.000000000 +0200
  7763. @@ -0,0 +1,310 @@
  7764. +/*
  7765. + * Atheros AR71xx SoC specific setup
  7766. + *
  7767. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7768. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7769. + *
  7770. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7771. + *
  7772. + * This program is free software; you can redistribute it and/or modify it
  7773. + * under the terms of the GNU General Public License version 2 as published
  7774. + * by the Free Software Foundation.
  7775. + */
  7776. +
  7777. +#include <linux/kernel.h>
  7778. +#include <linux/init.h>
  7779. +#include <linux/bootmem.h>
  7780. +
  7781. +#include <asm/bootinfo.h>
  7782. +#include <asm/time.h> /* for mips_hpt_frequency */
  7783. +#include <asm/reboot.h> /* for _machine_{restart,halt} */
  7784. +#include <asm/mips_machine.h>
  7785. +
  7786. +#include <asm/mach-ar71xx/ar71xx.h>
  7787. +
  7788. +#include "machtype.h"
  7789. +#include "devices.h"
  7790. +
  7791. +#define AR71XX_SYS_TYPE_LEN 64
  7792. +#define AR71XX_BASE_FREQ 40000000
  7793. +#define AR91XX_BASE_FREQ 5000000
  7794. +#define AR724X_BASE_FREQ 5000000
  7795. +
  7796. +u32 ar71xx_cpu_freq;
  7797. +EXPORT_SYMBOL_GPL(ar71xx_cpu_freq);
  7798. +
  7799. +u32 ar71xx_ahb_freq;
  7800. +EXPORT_SYMBOL_GPL(ar71xx_ahb_freq);
  7801. +
  7802. +u32 ar71xx_ddr_freq;
  7803. +EXPORT_SYMBOL_GPL(ar71xx_ddr_freq);
  7804. +
  7805. +enum ar71xx_soc_type ar71xx_soc;
  7806. +EXPORT_SYMBOL_GPL(ar71xx_soc);
  7807. +
  7808. +static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];
  7809. +
  7810. +static void ar71xx_restart(char *command)
  7811. +{
  7812. + ar71xx_device_stop(RESET_MODULE_FULL_CHIP);
  7813. + for (;;)
  7814. + if (cpu_wait)
  7815. + cpu_wait();
  7816. +}
  7817. +
  7818. +static void ar71xx_halt(void)
  7819. +{
  7820. + while (1)
  7821. + cpu_wait();
  7822. +}
  7823. +
  7824. +static void __init ar71xx_detect_mem_size(void)
  7825. +{
  7826. + unsigned long size;
  7827. +
  7828. + for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX;
  7829. + size <<= 1 ) {
  7830. + if (!memcmp(ar71xx_detect_mem_size,
  7831. + ar71xx_detect_mem_size + size, 1024))
  7832. + break;
  7833. + }
  7834. +
  7835. + add_memory_region(0, size, BOOT_MEM_RAM);
  7836. +}
  7837. +
  7838. +static void __init ar71xx_detect_sys_type(void)
  7839. +{
  7840. + char *chip = "????";
  7841. + u32 id;
  7842. + u32 major;
  7843. + u32 minor;
  7844. + u32 rev = 0;
  7845. +
  7846. + id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID);
  7847. + major = id & REV_ID_MAJOR_MASK;
  7848. +
  7849. + switch (major) {
  7850. + case REV_ID_MAJOR_AR71XX:
  7851. + minor = id & AR71XX_REV_ID_MINOR_MASK;
  7852. + rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
  7853. + rev &= AR71XX_REV_ID_REVISION_MASK;
  7854. + switch (minor) {
  7855. + case AR71XX_REV_ID_MINOR_AR7130:
  7856. + ar71xx_soc = AR71XX_SOC_AR7130;
  7857. + chip = "7130";
  7858. + break;
  7859. +
  7860. + case AR71XX_REV_ID_MINOR_AR7141:
  7861. + ar71xx_soc = AR71XX_SOC_AR7141;
  7862. + chip = "7141";
  7863. + break;
  7864. +
  7865. + case AR71XX_REV_ID_MINOR_AR7161:
  7866. + ar71xx_soc = AR71XX_SOC_AR7161;
  7867. + chip = "7161";
  7868. + break;
  7869. + }
  7870. + break;
  7871. +
  7872. + case REV_ID_MAJOR_AR7240:
  7873. + ar71xx_soc = AR71XX_SOC_AR7240;
  7874. + chip = "7240";
  7875. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7876. + break;
  7877. +
  7878. + case REV_ID_MAJOR_AR7241:
  7879. + ar71xx_soc = AR71XX_SOC_AR7241;
  7880. + chip = "7241";
  7881. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7882. + break;
  7883. +
  7884. + case REV_ID_MAJOR_AR7242:
  7885. + ar71xx_soc = AR71XX_SOC_AR7242;
  7886. + chip = "7242";
  7887. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7888. + break;
  7889. +
  7890. + case REV_ID_MAJOR_AR913X:
  7891. + minor = id & AR91XX_REV_ID_MINOR_MASK;
  7892. + rev = id >> AR91XX_REV_ID_REVISION_SHIFT;
  7893. + rev &= AR91XX_REV_ID_REVISION_MASK;
  7894. + switch (minor) {
  7895. + case AR91XX_REV_ID_MINOR_AR9130:
  7896. + ar71xx_soc = AR71XX_SOC_AR9130;
  7897. + chip = "9130";
  7898. + break;
  7899. +
  7900. + case AR91XX_REV_ID_MINOR_AR9132:
  7901. + ar71xx_soc = AR71XX_SOC_AR9132;
  7902. + chip = "9132";
  7903. + break;
  7904. + }
  7905. + break;
  7906. +
  7907. + default:
  7908. + panic("ar71xx: unknown chip id:0x%08x\n", id);
  7909. + }
  7910. +
  7911. + sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev);
  7912. +}
  7913. +
  7914. +static void __init ar91xx_detect_sys_frequency(void)
  7915. +{
  7916. + u32 pll;
  7917. + u32 freq;
  7918. + u32 div;
  7919. +
  7920. + pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
  7921. +
  7922. + div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
  7923. + freq = div * AR91XX_BASE_FREQ;
  7924. +
  7925. + ar71xx_cpu_freq = freq;
  7926. +
  7927. + div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1;
  7928. + ar71xx_ddr_freq = freq / div;
  7929. +
  7930. + div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2;
  7931. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7932. +}
  7933. +
  7934. +static void __init ar71xx_detect_sys_frequency(void)
  7935. +{
  7936. + u32 pll;
  7937. + u32 freq;
  7938. + u32 div;
  7939. +
  7940. + pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
  7941. +
  7942. + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
  7943. + freq = div * AR71XX_BASE_FREQ;
  7944. +
  7945. + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
  7946. + ar71xx_cpu_freq = freq / div;
  7947. +
  7948. + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
  7949. + ar71xx_ddr_freq = freq / div;
  7950. +
  7951. + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
  7952. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7953. +}
  7954. +
  7955. +static void __init ar724x_detect_sys_frequency(void)
  7956. +{
  7957. + u32 pll;
  7958. + u32 freq;
  7959. + u32 div;
  7960. +
  7961. + pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
  7962. +
  7963. + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
  7964. + freq = div * AR724X_BASE_FREQ;
  7965. +
  7966. + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
  7967. + freq *= div;
  7968. +
  7969. + ar71xx_cpu_freq = freq;
  7970. +
  7971. + div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
  7972. + ar71xx_ddr_freq = freq / div;
  7973. +
  7974. + div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
  7975. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7976. +}
  7977. +
  7978. +static void __init detect_sys_frequency(void)
  7979. +{
  7980. + switch (ar71xx_soc) {
  7981. + case AR71XX_SOC_AR7130:
  7982. + case AR71XX_SOC_AR7141:
  7983. + case AR71XX_SOC_AR7161:
  7984. + ar71xx_detect_sys_frequency();
  7985. + break;
  7986. +
  7987. + case AR71XX_SOC_AR7240:
  7988. + case AR71XX_SOC_AR7241:
  7989. + case AR71XX_SOC_AR7242:
  7990. + ar724x_detect_sys_frequency();
  7991. + break;
  7992. +
  7993. + case AR71XX_SOC_AR9130:
  7994. + case AR71XX_SOC_AR9132:
  7995. + ar91xx_detect_sys_frequency();
  7996. + break;
  7997. +
  7998. + default:
  7999. + BUG();
  8000. + }
  8001. +}
  8002. +
  8003. +const char *get_system_type(void)
  8004. +{
  8005. + return ar71xx_sys_type;
  8006. +}
  8007. +
  8008. +unsigned int __cpuinit get_c0_compare_irq(void)
  8009. +{
  8010. + return CP0_LEGACY_COMPARE_IRQ;
  8011. +}
  8012. +
  8013. +void __init plat_mem_setup(void)
  8014. +{
  8015. + set_io_port_base(KSEG1);
  8016. +
  8017. + ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
  8018. + AR71XX_DDR_CTRL_SIZE);
  8019. +
  8020. + ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
  8021. + AR71XX_PLL_SIZE);
  8022. +
  8023. + ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
  8024. + AR71XX_RESET_SIZE);
  8025. +
  8026. + ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  8027. +
  8028. + ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE,
  8029. + AR71XX_USB_CTRL_SIZE);
  8030. +
  8031. + ar71xx_detect_mem_size();
  8032. + ar71xx_detect_sys_type();
  8033. + detect_sys_frequency();
  8034. +
  8035. + printk(KERN_INFO
  8036. + "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n",
  8037. + ar71xx_sys_type,
  8038. + ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000,
  8039. + ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000,
  8040. + ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000);
  8041. +
  8042. + _machine_restart = ar71xx_restart;
  8043. + _machine_halt = ar71xx_halt;
  8044. + pm_power_off = ar71xx_halt;
  8045. +}
  8046. +
  8047. +void __init plat_time_init(void)
  8048. +{
  8049. + mips_hpt_frequency = ar71xx_cpu_freq / 2;
  8050. +}
  8051. +
  8052. +__setup("board=", mips_machtype_setup);
  8053. +
  8054. +static int __init ar71xx_machine_setup(void)
  8055. +{
  8056. + ar71xx_gpio_init();
  8057. +
  8058. + ar71xx_add_device_uart();
  8059. + ar71xx_add_device_wdt();
  8060. +
  8061. + mips_machine_setup();
  8062. + return 0;
  8063. +}
  8064. +
  8065. +arch_initcall(ar71xx_machine_setup);
  8066. +
  8067. +static void __init ar71xx_generic_init(void)
  8068. +{
  8069. + /* Nothing to do */
  8070. +}
  8071. +
  8072. +MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board",
  8073. + ar71xx_generic_init);
  8074. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h
  8075. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100
  8076. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-05-27 14:36:51.000000000 +0200
  8077. @@ -0,0 +1,514 @@
  8078. +/*
  8079. + * Atheros AR71xx SoC specific definitions
  8080. + *
  8081. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8082. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8083. + *
  8084. + * Parts of this file are based on Atheros' 2.6.15 BSP
  8085. + *
  8086. + * This program is free software; you can redistribute it and/or modify it
  8087. + * under the terms of the GNU General Public License version 2 as published
  8088. + * by the Free Software Foundation.
  8089. + */
  8090. +
  8091. +#ifndef __ASM_MACH_AR71XX_H
  8092. +#define __ASM_MACH_AR71XX_H
  8093. +
  8094. +#include <linux/types.h>
  8095. +#include <linux/init.h>
  8096. +#include <linux/io.h>
  8097. +#include <linux/bitops.h>
  8098. +
  8099. +#ifndef __ASSEMBLER__
  8100. +
  8101. +#define AR71XX_PCI_MEM_BASE 0x10000000
  8102. +#define AR71XX_PCI_MEM_SIZE 0x08000000
  8103. +#define AR71XX_APB_BASE 0x18000000
  8104. +#define AR71XX_GE0_BASE 0x19000000
  8105. +#define AR71XX_GE0_SIZE 0x01000000
  8106. +#define AR71XX_GE1_BASE 0x1a000000
  8107. +#define AR71XX_GE1_SIZE 0x01000000
  8108. +#define AR71XX_EHCI_BASE 0x1b000000
  8109. +#define AR71XX_EHCI_SIZE 0x01000000
  8110. +#define AR71XX_OHCI_BASE 0x1c000000
  8111. +#define AR71XX_OHCI_SIZE 0x01000000
  8112. +#define AR7240_OHCI_BASE 0x1b000000
  8113. +#define AR7240_OHCI_SIZE 0x01000000
  8114. +#define AR71XX_SPI_BASE 0x1f000000
  8115. +#define AR71XX_SPI_SIZE 0x01000000
  8116. +
  8117. +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
  8118. +#define AR71XX_DDR_CTRL_SIZE 0x10000
  8119. +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
  8120. +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  8121. +#define AR71XX_UART_SIZE 0x10000
  8122. +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
  8123. +#define AR71XX_USB_CTRL_SIZE 0x10000
  8124. +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
  8125. +#define AR71XX_GPIO_SIZE 0x10000
  8126. +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
  8127. +#define AR71XX_PLL_SIZE 0x10000
  8128. +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
  8129. +#define AR71XX_RESET_SIZE 0x10000
  8130. +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
  8131. +#define AR71XX_MII_SIZE 0x10000
  8132. +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
  8133. +#define AR71XX_SLIC_SIZE 0x10000
  8134. +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
  8135. +#define AR71XX_DMA_SIZE 0x10000
  8136. +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
  8137. +#define AR71XX_STEREO_SIZE 0x10000
  8138. +
  8139. +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
  8140. +#define AR724X_PCI_CRP_SIZE 0x100
  8141. +
  8142. +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
  8143. +#define AR724X_PCI_CTRL_SIZE 0x100
  8144. +
  8145. +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
  8146. +#define AR91XX_WMAC_SIZE 0x30000
  8147. +
  8148. +#define AR71XX_MEM_SIZE_MIN 0x0200000
  8149. +#define AR71XX_MEM_SIZE_MAX 0x10000000
  8150. +
  8151. +#define AR71XX_CPU_IRQ_BASE 0
  8152. +#define AR71XX_MISC_IRQ_BASE 8
  8153. +#define AR71XX_MISC_IRQ_COUNT 8
  8154. +#define AR71XX_GPIO_IRQ_BASE 16
  8155. +#define AR71XX_GPIO_IRQ_COUNT 32
  8156. +#define AR71XX_PCI_IRQ_BASE 48
  8157. +#define AR71XX_PCI_IRQ_COUNT 8
  8158. +
  8159. +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
  8160. +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
  8161. +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
  8162. +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
  8163. +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
  8164. +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
  8165. +
  8166. +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
  8167. +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
  8168. +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
  8169. +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
  8170. +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
  8171. +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
  8172. +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
  8173. +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
  8174. +
  8175. +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
  8176. +
  8177. +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
  8178. +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
  8179. +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
  8180. +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
  8181. +
  8182. +extern u32 ar71xx_ahb_freq;
  8183. +extern u32 ar71xx_cpu_freq;
  8184. +extern u32 ar71xx_ddr_freq;
  8185. +
  8186. +enum ar71xx_soc_type {
  8187. + AR71XX_SOC_UNKNOWN,
  8188. + AR71XX_SOC_AR7130,
  8189. + AR71XX_SOC_AR7141,
  8190. + AR71XX_SOC_AR7161,
  8191. + AR71XX_SOC_AR7240,
  8192. + AR71XX_SOC_AR7241,
  8193. + AR71XX_SOC_AR7242,
  8194. + AR71XX_SOC_AR9130,
  8195. + AR71XX_SOC_AR9132
  8196. +};
  8197. +
  8198. +extern enum ar71xx_soc_type ar71xx_soc;
  8199. +
  8200. +/*
  8201. + * PLL block
  8202. + */
  8203. +#define AR71XX_PLL_REG_CPU_CONFIG 0x00
  8204. +#define AR71XX_PLL_REG_SEC_CONFIG 0x04
  8205. +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
  8206. +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
  8207. +
  8208. +#define AR71XX_PLL_DIV_SHIFT 3
  8209. +#define AR71XX_PLL_DIV_MASK 0x1f
  8210. +#define AR71XX_CPU_DIV_SHIFT 16
  8211. +#define AR71XX_CPU_DIV_MASK 0x3
  8212. +#define AR71XX_DDR_DIV_SHIFT 18
  8213. +#define AR71XX_DDR_DIV_MASK 0x3
  8214. +#define AR71XX_AHB_DIV_SHIFT 20
  8215. +#define AR71XX_AHB_DIV_MASK 0x7
  8216. +
  8217. +#define AR71XX_ETH0_PLL_SHIFT 17
  8218. +#define AR71XX_ETH1_PLL_SHIFT 19
  8219. +
  8220. +#define AR724X_PLL_REG_CPU_CONFIG 0x00
  8221. +#define AR724X_PLL_REG_PCIE_CONFIG 0x18
  8222. +
  8223. +#define AR724X_PLL_DIV_SHIFT 0
  8224. +#define AR724X_PLL_DIV_MASK 0x3ff
  8225. +#define AR724X_PLL_REF_DIV_SHIFT 10
  8226. +#define AR724X_PLL_REF_DIV_MASK 0xf
  8227. +#define AR724X_AHB_DIV_SHIFT 19
  8228. +#define AR724X_AHB_DIV_MASK 0x1
  8229. +#define AR724X_DDR_DIV_SHIFT 22
  8230. +#define AR724X_DDR_DIV_MASK 0x3
  8231. +
  8232. +#define AR91XX_PLL_REG_CPU_CONFIG 0x00
  8233. +#define AR91XX_PLL_REG_ETH_CONFIG 0x04
  8234. +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
  8235. +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
  8236. +
  8237. +#define AR91XX_PLL_DIV_SHIFT 0
  8238. +#define AR91XX_PLL_DIV_MASK 0x3ff
  8239. +#define AR91XX_DDR_DIV_SHIFT 22
  8240. +#define AR91XX_DDR_DIV_MASK 0x3
  8241. +#define AR91XX_AHB_DIV_SHIFT 19
  8242. +#define AR91XX_AHB_DIV_MASK 0x1
  8243. +
  8244. +#define AR91XX_ETH0_PLL_SHIFT 20
  8245. +#define AR91XX_ETH1_PLL_SHIFT 22
  8246. +
  8247. +extern void __iomem *ar71xx_pll_base;
  8248. +
  8249. +static inline void ar71xx_pll_wr(unsigned reg, u32 val)
  8250. +{
  8251. + __raw_writel(val, ar71xx_pll_base + reg);
  8252. +}
  8253. +
  8254. +static inline u32 ar71xx_pll_rr(unsigned reg)
  8255. +{
  8256. + return __raw_readl(ar71xx_pll_base + reg);
  8257. +}
  8258. +
  8259. +/*
  8260. + * USB_CONFIG block
  8261. + */
  8262. +#define USB_CTRL_REG_FLADJ 0x00
  8263. +#define USB_CTRL_REG_CONFIG 0x04
  8264. +
  8265. +extern void __iomem *ar71xx_usb_ctrl_base;
  8266. +
  8267. +static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
  8268. +{
  8269. + __raw_writel(val, ar71xx_usb_ctrl_base + reg);
  8270. +}
  8271. +
  8272. +static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
  8273. +{
  8274. + return __raw_readl(ar71xx_usb_ctrl_base + reg);
  8275. +}
  8276. +
  8277. +/*
  8278. + * GPIO block
  8279. + */
  8280. +#define GPIO_REG_OE 0x00
  8281. +#define GPIO_REG_IN 0x04
  8282. +#define GPIO_REG_OUT 0x08
  8283. +#define GPIO_REG_SET 0x0c
  8284. +#define GPIO_REG_CLEAR 0x10
  8285. +#define GPIO_REG_INT_MODE 0x14
  8286. +#define GPIO_REG_INT_TYPE 0x18
  8287. +#define GPIO_REG_INT_POLARITY 0x1c
  8288. +#define GPIO_REG_INT_PENDING 0x20
  8289. +#define GPIO_REG_INT_ENABLE 0x24
  8290. +#define GPIO_REG_FUNC 0x28
  8291. +
  8292. +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
  8293. +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
  8294. +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
  8295. +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
  8296. +#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
  8297. +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
  8298. +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
  8299. +
  8300. +#define AR71XX_GPIO_COUNT 16
  8301. +
  8302. +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
  8303. +#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
  8304. +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
  8305. +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
  8306. +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
  8307. +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
  8308. +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
  8309. +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
  8310. +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
  8311. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
  8312. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
  8313. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
  8314. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
  8315. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
  8316. +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
  8317. +#define AR724X_GPIO_FUNC_UART_EN BIT(1)
  8318. +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
  8319. +
  8320. +#define AR724X_GPIO_COUNT 18
  8321. +
  8322. +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
  8323. +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
  8324. +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
  8325. +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
  8326. +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
  8327. +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
  8328. +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
  8329. +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
  8330. +#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
  8331. +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
  8332. +
  8333. +#define AR91XX_GPIO_COUNT 22
  8334. +
  8335. +extern void __iomem *ar71xx_gpio_base;
  8336. +
  8337. +static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
  8338. +{
  8339. + __raw_writel(value, ar71xx_gpio_base + reg);
  8340. +}
  8341. +
  8342. +static inline u32 ar71xx_gpio_rr(unsigned reg)
  8343. +{
  8344. + return __raw_readl(ar71xx_gpio_base + reg);
  8345. +}
  8346. +
  8347. +void ar71xx_gpio_init(void) __init;
  8348. +void ar71xx_gpio_function_enable(u32 mask);
  8349. +void ar71xx_gpio_function_disable(u32 mask);
  8350. +void ar71xx_gpio_function_setup(u32 set, u32 clear);
  8351. +
  8352. +/*
  8353. + * DDR_CTRL block
  8354. + */
  8355. +#define AR71XX_DDR_REG_PCI_WIN0 0x7c
  8356. +#define AR71XX_DDR_REG_PCI_WIN1 0x80
  8357. +#define AR71XX_DDR_REG_PCI_WIN2 0x84
  8358. +#define AR71XX_DDR_REG_PCI_WIN3 0x88
  8359. +#define AR71XX_DDR_REG_PCI_WIN4 0x8c
  8360. +#define AR71XX_DDR_REG_PCI_WIN5 0x90
  8361. +#define AR71XX_DDR_REG_PCI_WIN6 0x94
  8362. +#define AR71XX_DDR_REG_PCI_WIN7 0x98
  8363. +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
  8364. +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
  8365. +#define AR71XX_DDR_REG_FLUSH_USB 0xa4
  8366. +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
  8367. +
  8368. +#define AR724X_DDR_REG_FLUSH_GE0 0x7c
  8369. +#define AR724X_DDR_REG_FLUSH_GE1 0x80
  8370. +#define AR724X_DDR_REG_FLUSH_USB 0x84
  8371. +#define AR724X_DDR_REG_FLUSH_PCIE 0x88
  8372. +
  8373. +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
  8374. +#define AR91XX_DDR_REG_FLUSH_GE1 0x80
  8375. +#define AR91XX_DDR_REG_FLUSH_USB 0x84
  8376. +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
  8377. +
  8378. +#define PCI_WIN0_OFFS 0x10000000
  8379. +#define PCI_WIN1_OFFS 0x11000000
  8380. +#define PCI_WIN2_OFFS 0x12000000
  8381. +#define PCI_WIN3_OFFS 0x13000000
  8382. +#define PCI_WIN4_OFFS 0x14000000
  8383. +#define PCI_WIN5_OFFS 0x15000000
  8384. +#define PCI_WIN6_OFFS 0x16000000
  8385. +#define PCI_WIN7_OFFS 0x07000000
  8386. +
  8387. +extern void __iomem *ar71xx_ddr_base;
  8388. +
  8389. +static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
  8390. +{
  8391. + __raw_writel(val, ar71xx_ddr_base + reg);
  8392. +}
  8393. +
  8394. +static inline u32 ar71xx_ddr_rr(unsigned reg)
  8395. +{
  8396. + return __raw_readl(ar71xx_ddr_base + reg);
  8397. +}
  8398. +
  8399. +void ar71xx_ddr_flush(u32 reg);
  8400. +
  8401. +/*
  8402. + * PCI block
  8403. + */
  8404. +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
  8405. +#define AR71XX_PCI_CFG_SIZE 0x100
  8406. +
  8407. +#define PCI_REG_CRP_AD_CBE 0x00
  8408. +#define PCI_REG_CRP_WRDATA 0x04
  8409. +#define PCI_REG_CRP_RDDATA 0x08
  8410. +#define PCI_REG_CFG_AD 0x0c
  8411. +#define PCI_REG_CFG_CBE 0x10
  8412. +#define PCI_REG_CFG_WRDATA 0x14
  8413. +#define PCI_REG_CFG_RDDATA 0x18
  8414. +#define PCI_REG_PCI_ERR 0x1c
  8415. +#define PCI_REG_PCI_ERR_ADDR 0x20
  8416. +#define PCI_REG_AHB_ERR 0x24
  8417. +#define PCI_REG_AHB_ERR_ADDR 0x28
  8418. +
  8419. +#define PCI_CRP_CMD_WRITE 0x00010000
  8420. +#define PCI_CRP_CMD_READ 0x00000000
  8421. +#define PCI_CFG_CMD_READ 0x0000000a
  8422. +#define PCI_CFG_CMD_WRITE 0x0000000b
  8423. +
  8424. +#define PCI_IDSEL_ADL_START 17
  8425. +
  8426. +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
  8427. +#define AR724X_PCI_CFG_SIZE 0x1000
  8428. +
  8429. +#define AR724X_PCI_REG_APP 0x00
  8430. +#define AR724X_PCI_REG_RESET 0x18
  8431. +#define AR724X_PCI_REG_INT_STATUS 0x4c
  8432. +#define AR724X_PCI_REG_INT_MASK 0x50
  8433. +
  8434. +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
  8435. +#define AR724X_PCI_RESET_LINK_UP BIT(0)
  8436. +
  8437. +#define AR724X_PCI_INT_DEV0 BIT(14)
  8438. +
  8439. +/*
  8440. + * RESET block
  8441. + */
  8442. +#define AR71XX_RESET_REG_TIMER 0x00
  8443. +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
  8444. +#define AR71XX_RESET_REG_WDOG_CTRL 0x08
  8445. +#define AR71XX_RESET_REG_WDOG 0x0c
  8446. +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
  8447. +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
  8448. +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
  8449. +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
  8450. +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
  8451. +#define AR71XX_RESET_REG_RESET_MODULE 0x24
  8452. +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
  8453. +#define AR71XX_RESET_REG_PERFC0 0x30
  8454. +#define AR71XX_RESET_REG_PERFC1 0x34
  8455. +#define AR71XX_RESET_REG_REV_ID 0x90
  8456. +
  8457. +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
  8458. +#define AR91XX_RESET_REG_RESET_MODULE 0x1c
  8459. +#define AR91XX_RESET_REG_PERF_CTRL 0x20
  8460. +#define AR91XX_RESET_REG_PERFC0 0x24
  8461. +#define AR91XX_RESET_REG_PERFC1 0x28
  8462. +
  8463. +#define AR724X_RESET_REG_RESET_MODULE 0x1c
  8464. +
  8465. +#define WDOG_CTRL_LAST_RESET BIT(31)
  8466. +#define WDOG_CTRL_ACTION_MASK 3
  8467. +#define WDOG_CTRL_ACTION_NONE 0 /* no action */
  8468. +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
  8469. +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
  8470. +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
  8471. +
  8472. +#define MISC_INT_DMA BIT(7)
  8473. +#define MISC_INT_OHCI BIT(6)
  8474. +#define MISC_INT_PERFC BIT(5)
  8475. +#define MISC_INT_WDOG BIT(4)
  8476. +#define MISC_INT_UART BIT(3)
  8477. +#define MISC_INT_GPIO BIT(2)
  8478. +#define MISC_INT_ERROR BIT(1)
  8479. +#define MISC_INT_TIMER BIT(0)
  8480. +
  8481. +#define PCI_INT_CORE BIT(4)
  8482. +#define PCI_INT_DEV2 BIT(2)
  8483. +#define PCI_INT_DEV1 BIT(1)
  8484. +#define PCI_INT_DEV0 BIT(0)
  8485. +
  8486. +#define RESET_MODULE_EXTERNAL BIT(28)
  8487. +#define RESET_MODULE_FULL_CHIP BIT(24)
  8488. +#define RESET_MODULE_AMBA2WMAC BIT(22)
  8489. +#define RESET_MODULE_CPU_NMI BIT(21)
  8490. +#define RESET_MODULE_CPU_COLD BIT(20)
  8491. +#define RESET_MODULE_DMA BIT(19)
  8492. +#define RESET_MODULE_SLIC BIT(18)
  8493. +#define RESET_MODULE_STEREO BIT(17)
  8494. +#define RESET_MODULE_DDR BIT(16)
  8495. +#define RESET_MODULE_GE1_MAC BIT(13)
  8496. +#define RESET_MODULE_GE1_PHY BIT(12)
  8497. +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
  8498. +#define RESET_MODULE_GE0_MAC BIT(9)
  8499. +#define RESET_MODULE_GE0_PHY BIT(8)
  8500. +#define RESET_MODULE_USB_OHCI_DLL BIT(6)
  8501. +#define RESET_MODULE_USB_HOST BIT(5)
  8502. +#define RESET_MODULE_USB_PHY BIT(4)
  8503. +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
  8504. +#define RESET_MODULE_PCI_BUS BIT(1)
  8505. +#define RESET_MODULE_PCI_CORE BIT(0)
  8506. +
  8507. +#define AR724X_RESET_GE1_MDIO BIT(23)
  8508. +#define AR724X_RESET_GE0_MDIO BIT(22)
  8509. +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
  8510. +#define AR724X_RESET_PCIE_PHY BIT(7)
  8511. +#define AR724X_RESET_PCIE BIT(6)
  8512. +
  8513. +#define REV_ID_MAJOR_MASK 0xfff0
  8514. +#define REV_ID_MAJOR_AR71XX 0x00a0
  8515. +#define REV_ID_MAJOR_AR913X 0x00b0
  8516. +#define REV_ID_MAJOR_AR7240 0x00c0
  8517. +#define REV_ID_MAJOR_AR7241 0x0100
  8518. +#define REV_ID_MAJOR_AR7242 0x1100
  8519. +
  8520. +#define AR71XX_REV_ID_MINOR_MASK 0x3
  8521. +#define AR71XX_REV_ID_MINOR_AR7130 0x0
  8522. +#define AR71XX_REV_ID_MINOR_AR7141 0x1
  8523. +#define AR71XX_REV_ID_MINOR_AR7161 0x2
  8524. +#define AR71XX_REV_ID_REVISION_MASK 0x3
  8525. +#define AR71XX_REV_ID_REVISION_SHIFT 2
  8526. +
  8527. +#define AR91XX_REV_ID_MINOR_MASK 0x3
  8528. +#define AR91XX_REV_ID_MINOR_AR9130 0x0
  8529. +#define AR91XX_REV_ID_MINOR_AR9132 0x1
  8530. +#define AR91XX_REV_ID_REVISION_MASK 0x3
  8531. +#define AR91XX_REV_ID_REVISION_SHIFT 2
  8532. +
  8533. +#define AR724X_REV_ID_REVISION_MASK 0x3
  8534. +
  8535. +extern void __iomem *ar71xx_reset_base;
  8536. +
  8537. +static inline void ar71xx_reset_wr(unsigned reg, u32 val)
  8538. +{
  8539. + __raw_writel(val, ar71xx_reset_base + reg);
  8540. +}
  8541. +
  8542. +static inline u32 ar71xx_reset_rr(unsigned reg)
  8543. +{
  8544. + return __raw_readl(ar71xx_reset_base + reg);
  8545. +}
  8546. +
  8547. +void ar71xx_device_stop(u32 mask);
  8548. +void ar71xx_device_start(u32 mask);
  8549. +int ar71xx_device_stopped(u32 mask);
  8550. +
  8551. +/*
  8552. + * SPI block
  8553. + */
  8554. +#define SPI_REG_FS 0x00 /* Function Select */
  8555. +#define SPI_REG_CTRL 0x04 /* SPI Control */
  8556. +#define SPI_REG_IOC 0x08 /* SPI I/O Control */
  8557. +#define SPI_REG_RDS 0x0c /* Read Data Shift */
  8558. +
  8559. +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
  8560. +
  8561. +#define SPI_CTRL_RD BIT(6) /* Remap Disable */
  8562. +#define SPI_CTRL_DIV_MASK 0x3f
  8563. +
  8564. +#define SPI_IOC_DO BIT(0) /* Data Out pin */
  8565. +#define SPI_IOC_CLK BIT(8) /* CLK pin */
  8566. +#define SPI_IOC_CS(n) BIT(16 + (n))
  8567. +#define SPI_IOC_CS0 SPI_IOC_CS(0)
  8568. +#define SPI_IOC_CS1 SPI_IOC_CS(1)
  8569. +#define SPI_IOC_CS2 SPI_IOC_CS(2)
  8570. +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
  8571. +
  8572. +void ar71xx_flash_acquire(void);
  8573. +void ar71xx_flash_release(void);
  8574. +
  8575. +/*
  8576. + * MII_CTRL block
  8577. + */
  8578. +#define MII_REG_MII0_CTRL 0x00
  8579. +#define MII_REG_MII1_CTRL 0x04
  8580. +
  8581. +#define MII0_CTRL_IF_GMII 0
  8582. +#define MII0_CTRL_IF_MII 1
  8583. +#define MII0_CTRL_IF_RGMII 2
  8584. +#define MII0_CTRL_IF_RMII 3
  8585. +
  8586. +#define MII1_CTRL_IF_RGMII 0
  8587. +#define MII1_CTRL_IF_RMII 1
  8588. +
  8589. +#endif /* __ASSEMBLER__ */
  8590. +
  8591. +#endif /* __ASM_MACH_AR71XX_H */
  8592. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h
  8593. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100
  8594. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-05-27 14:36:51.000000000 +0200
  8595. @@ -0,0 +1,26 @@
  8596. +/*
  8597. + * AR91xx parallel flash driver platform data definitions
  8598. + *
  8599. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8600. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8601. + *
  8602. + * This program is free software; you can redistribute it and/or modify it
  8603. + * under the terms of the GNU General Public License version 2 as published
  8604. + * by the Free Software Foundation.
  8605. + */
  8606. +
  8607. +#ifndef __AR91XX_FLASH_H
  8608. +#define __AR91XX_FLASH_H
  8609. +
  8610. +struct mtd_partition;
  8611. +
  8612. +struct ar91xx_flash_platform_data {
  8613. + unsigned int width;
  8614. + u8 is_shared:1;
  8615. +#ifdef CONFIG_MTD_PARTITIONS
  8616. + unsigned int nr_parts;
  8617. + struct mtd_partition *parts;
  8618. +#endif
  8619. +};
  8620. +
  8621. +#endif /* __AR91XX_FLASH_H */
  8622. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h
  8623. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100
  8624. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-05-27 14:36:51.000000000 +0200
  8625. @@ -0,0 +1,56 @@
  8626. +/*
  8627. + * Atheros AR71xx specific CPU feature overrides
  8628. + *
  8629. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8630. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8631. + *
  8632. + * This file was derived from: include/asm-mips/cpu-features.h
  8633. + * Copyright (C) 2003, 2004 Ralf Baechle
  8634. + * Copyright (C) 2004 Maciej W. Rozycki
  8635. + *
  8636. + * This program is free software; you can redistribute it and/or modify it
  8637. + * under the terms of the GNU General Public License version 2 as published
  8638. + * by the Free Software Foundation.
  8639. + *
  8640. + */
  8641. +#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8642. +#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8643. +
  8644. +#define cpu_has_tlb 1
  8645. +#define cpu_has_4kex 1
  8646. +#define cpu_has_3k_cache 0
  8647. +#define cpu_has_4k_cache 1
  8648. +#define cpu_has_tx39_cache 0
  8649. +#define cpu_has_sb1_cache 0
  8650. +#define cpu_has_fpu 0
  8651. +#define cpu_has_32fpr 0
  8652. +#define cpu_has_counter 1
  8653. +#define cpu_has_watch 1
  8654. +#define cpu_has_divec 1
  8655. +
  8656. +#define cpu_has_prefetch 1
  8657. +#define cpu_has_ejtag 1
  8658. +#define cpu_has_llsc 1
  8659. +
  8660. +#define cpu_has_mips16 1
  8661. +#define cpu_has_mdmx 0
  8662. +#define cpu_has_mips3d 0
  8663. +#define cpu_has_smartmips 0
  8664. +
  8665. +#define cpu_has_mips32r1 1
  8666. +#define cpu_has_mips32r2 1
  8667. +#define cpu_has_mips64r1 0
  8668. +#define cpu_has_mips64r2 0
  8669. +
  8670. +#define cpu_has_dsp 0
  8671. +#define cpu_has_mipsmt 0
  8672. +
  8673. +#define cpu_has_64bits 0
  8674. +#define cpu_has_64bit_zero_reg 0
  8675. +#define cpu_has_64bit_gp_regs 0
  8676. +#define cpu_has_64bit_addresses 0
  8677. +
  8678. +#define cpu_dcache_line_size() 32
  8679. +#define cpu_icache_line_size() 32
  8680. +
  8681. +#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */
  8682. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h
  8683. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100
  8684. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-05-27 14:36:51.000000000 +0200
  8685. @@ -0,0 +1,53 @@
  8686. +/*
  8687. + * Atheros AR71xx GPIO API definitions
  8688. + *
  8689. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8690. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8691. + *
  8692. + * This program is free software; you can redistribute it and/or modify it
  8693. + * under the terms of the GNU General Public License version 2 as published
  8694. + * by the Free Software Foundation.
  8695. + *
  8696. + */
  8697. +
  8698. +#ifndef __ASM_MACH_AR71XX_GPIO_H
  8699. +#define __ASM_MACH_AR71XX_GPIO_H
  8700. +
  8701. +#define ARCH_NR_GPIOS 64
  8702. +#include <asm-generic/gpio.h>
  8703. +
  8704. +#include <asm/mach-ar71xx/ar71xx.h>
  8705. +
  8706. +extern unsigned long ar71xx_gpio_count;
  8707. +extern void __ar71xx_gpio_set_value(unsigned gpio, int value);
  8708. +extern int __ar71xx_gpio_get_value(unsigned gpio);
  8709. +
  8710. +static inline int gpio_to_irq(unsigned gpio)
  8711. +{
  8712. + return AR71XX_GPIO_IRQ(gpio);
  8713. +}
  8714. +
  8715. +static inline int irq_to_gpio(unsigned irq)
  8716. +{
  8717. + return irq - AR71XX_GPIO_IRQ_BASE;
  8718. +}
  8719. +
  8720. +static inline int gpio_get_value(unsigned gpio)
  8721. +{
  8722. + if (gpio < ar71xx_gpio_count)
  8723. + return __ar71xx_gpio_get_value(gpio);
  8724. +
  8725. + return __gpio_get_value(gpio);
  8726. +}
  8727. +
  8728. +static inline void gpio_set_value(unsigned gpio, int value)
  8729. +{
  8730. + if (gpio < ar71xx_gpio_count)
  8731. + __ar71xx_gpio_set_value(gpio, value);
  8732. + else
  8733. + __gpio_set_value(gpio, value);
  8734. +}
  8735. +
  8736. +#define gpio_cansleep __gpio_cansleep
  8737. +
  8738. +#endif /* __ASM_MACH_AR71XX_GPIO_H */
  8739. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h
  8740. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100
  8741. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-05-27 14:36:51.000000000 +0200
  8742. @@ -0,0 +1,17 @@
  8743. +/*
  8744. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8745. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8746. + *
  8747. + * This program is free software; you can redistribute it and/or modify it
  8748. + * under the terms of the GNU General Public License version 2 as published
  8749. + * by the Free Software Foundation.
  8750. + */
  8751. +#ifndef __ASM_MACH_AR71XX_IRQ_H
  8752. +#define __ASM_MACH_AR71XX_IRQ_H
  8753. +
  8754. +#define MIPS_CPU_IRQ_BASE 0
  8755. +#define NR_IRQS 56
  8756. +
  8757. +#include_next <irq.h>
  8758. +
  8759. +#endif /* __ASM_MACH_AR71XX_IRQ_H */
  8760. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h
  8761. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
  8762. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-05-27 14:36:51.000000000 +0200
  8763. @@ -0,0 +1,32 @@
  8764. +/*
  8765. + * Atheros AR71xx specific kernel entry setup
  8766. + *
  8767. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  8768. + *
  8769. + * This program is free software; you can redistribute it and/or modify it
  8770. + * under the terms of the GNU General Public License version 2 as published
  8771. + * by the Free Software Foundation.
  8772. + *
  8773. + */
  8774. +#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8775. +#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8776. +
  8777. + /*
  8778. + * Some bootloaders set the 'Kseg0 coherency algorithm' to
  8779. + * 'Cacheable, noncoherent, write-through, no write allocate'
  8780. + * and this cause performance issues. Let's go and change it to
  8781. + * 'Cacheable, noncoherent, write-back, write allocate'
  8782. + */
  8783. + .macro kernel_entry_setup
  8784. + mfc0 t0, CP0_CONFIG
  8785. + li t1, ~CONF_CM_CMASK
  8786. + and t0, t1
  8787. + ori t0, CONF_CM_CACHABLE_NONCOHERENT
  8788. + mtc0 t0, CP0_CONFIG
  8789. + nop
  8790. + .endm
  8791. +
  8792. + .macro smp_slave_setup
  8793. + .endm
  8794. +
  8795. +#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */
  8796. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h
  8797. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100
  8798. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-05-27 14:36:51.000000000 +0200
  8799. @@ -0,0 +1,66 @@
  8800. +/*
  8801. + * MikroTik RouterBOARD 750 definitions
  8802. + *
  8803. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  8804. + *
  8805. + * This program is free software; you can redistribute it and/or modify it
  8806. + * under the terms of the GNU General Public License version 2 as published
  8807. + * by the Free Software Foundation.
  8808. + */
  8809. +#ifndef _MACH_RB750_H
  8810. +#define _MACH_RB750_H
  8811. +
  8812. +#include <linux/bitops.h>
  8813. +
  8814. +#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */
  8815. +#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */
  8816. +#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */
  8817. +#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */
  8818. +#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */
  8819. +#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */
  8820. +#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */
  8821. +#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */
  8822. +#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */
  8823. +#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */
  8824. +#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */
  8825. +#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */
  8826. +#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */
  8827. +#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */
  8828. +#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */
  8829. +
  8830. +#define RB750_GPIO_BTN_RESET 1
  8831. +#define RB750_GPIO_SPI_CS0 2
  8832. +#define RB750_GPIO_LED_ACT 12
  8833. +#define RB750_GPIO_LED_PORT1 13
  8834. +#define RB750_GPIO_LED_PORT2 14
  8835. +#define RB750_GPIO_LED_PORT3 15
  8836. +#define RB750_GPIO_LED_PORT4 16
  8837. +#define RB750_GPIO_LED_PORT5 17
  8838. +
  8839. +#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT)
  8840. +#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1)
  8841. +#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2)
  8842. +#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3)
  8843. +#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4)
  8844. +#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5)
  8845. +
  8846. +#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE)
  8847. +
  8848. +#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \
  8849. + RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT)
  8850. +
  8851. +struct rb750_led_data {
  8852. + char *name;
  8853. + char *default_trigger;
  8854. + u32 mask;
  8855. + int active_low;
  8856. +};
  8857. +
  8858. +struct rb750_led_platform_data {
  8859. + int num_leds;
  8860. + struct rb750_led_data *leds;
  8861. +};
  8862. +
  8863. +int rb750_latch_change(u32 mask_clr, u32 mask_set);
  8864. +
  8865. +#endif /* _MACH_RB750_H */
  8866. \ No newline at end of file
  8867. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h
  8868. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100
  8869. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-05-27 14:36:51.000000000 +0200
  8870. @@ -0,0 +1,45 @@
  8871. +/*
  8872. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8873. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8874. + *
  8875. + * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
  8876. + * Copyright (C) 2003, 2004 Ralf Baechle
  8877. + *
  8878. + * This program is free software; you can redistribute it and/or modify it
  8879. + * under the terms of the GNU General Public License version 2 as published
  8880. + * by the Free Software Foundation.
  8881. + */
  8882. +
  8883. +#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H
  8884. +#define __ASM_MACH_AR71XX_MANGLE_PORT_H
  8885. +
  8886. +#define __swizzle_addr_b(port) ((port) ^ 3)
  8887. +#define __swizzle_addr_w(port) ((port) ^ 2)
  8888. +#define __swizzle_addr_l(port) (port)
  8889. +#define __swizzle_addr_q(port) (port)
  8890. +
  8891. +#if defined(CONFIG_SWAP_IO_SPACE)
  8892. +
  8893. +# define ioswabb(a, x) (x)
  8894. +# define __mem_ioswabb(a, x) (x)
  8895. +# define ioswabw(a, x) le16_to_cpu(x)
  8896. +# define __mem_ioswabw(a, x) (x)
  8897. +# define ioswabl(a, x) le32_to_cpu(x)
  8898. +# define __mem_ioswabl(a, x) (x)
  8899. +# define ioswabq(a, x) le64_to_cpu(x)
  8900. +# define __mem_ioswabq(a, x) (x)
  8901. +
  8902. +#else
  8903. +
  8904. +# define ioswabb(a, x) (x)
  8905. +# define __mem_ioswabb(a, x) (x)
  8906. +# define ioswabw(a, x) (x)
  8907. +# define __mem_ioswabw(a, x) cpu_to_le16(x)
  8908. +# define ioswabl(a, x) (x)
  8909. +# define __mem_ioswabl(a, x) cpu_to_le32(x)
  8910. +# define ioswabq(a, x) (x)
  8911. +# define __mem_ioswabq(a, x) cpu_to_le64(x)
  8912. +
  8913. +#endif
  8914. +
  8915. +#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */
  8916. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h
  8917. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100
  8918. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-05-27 14:36:51.000000000 +0200
  8919. @@ -0,0 +1,39 @@
  8920. +/*
  8921. + * Atheros AR71xx SoC specific PCI definitions
  8922. + *
  8923. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8924. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8925. + *
  8926. + * This program is free software; you can redistribute it and/or modify it
  8927. + * under the terms of the GNU General Public License version 2 as published
  8928. + * by the Free Software Foundation.
  8929. + */
  8930. +
  8931. +#ifndef __ASM_MACH_AR71XX_PCI_H
  8932. +#define __ASM_MACH_AR71XX_PCI_H
  8933. +
  8934. +struct pci_dev;
  8935. +
  8936. +struct ar71xx_pci_irq {
  8937. + int irq;
  8938. + u8 slot;
  8939. + u8 pin;
  8940. +};
  8941. +
  8942. +extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  8943. +extern unsigned ar71xx_pci_nr_irqs __initdata;
  8944. +extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  8945. +
  8946. +int ar71xx_pcibios_map_irq(const struct pci_dev *dev,
  8947. + uint8_t slot, uint8_t pin) __init;
  8948. +int ar71xx_pcibios_init(void) __init;
  8949. +
  8950. +int ar71xx_pci_be_handler(int is_fixup);
  8951. +
  8952. +int ar724x_pcibios_map_irq(const struct pci_dev *dev,
  8953. + uint8_t slot, uint8_t pin) __init;
  8954. +int ar724x_pcibios_init(void) __init;
  8955. +
  8956. +int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init;
  8957. +
  8958. +#endif /* __ASM_MACH_AR71XX_PCI_H */
  8959. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h
  8960. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100
  8961. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-05-27 14:36:51.000000000 +0200
  8962. @@ -0,0 +1,61 @@
  8963. +/*
  8964. + * Atheros AR71xx SoC specific platform data definitions
  8965. + *
  8966. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8967. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8968. + *
  8969. + * This program is free software; you can redistribute it and/or modify it
  8970. + * under the terms of the GNU General Public License version 2 as published
  8971. + * by the Free Software Foundation.
  8972. + */
  8973. +
  8974. +#ifndef __ASM_MACH_AR71XX_PLATFORM_H
  8975. +#define __ASM_MACH_AR71XX_PLATFORM_H
  8976. +
  8977. +#include <linux/if_ether.h>
  8978. +#include <linux/skbuff.h>
  8979. +#include <linux/phy.h>
  8980. +#include <linux/spi/spi.h>
  8981. +
  8982. +struct ag71xx_platform_data {
  8983. + phy_interface_t phy_if_mode;
  8984. + u32 phy_mask;
  8985. + int speed;
  8986. + int duplex;
  8987. + u32 reset_bit;
  8988. + u32 mii_if;
  8989. + u8 mac_addr[ETH_ALEN];
  8990. + struct device *mii_bus_dev;
  8991. +
  8992. + u8 has_gbit:1;
  8993. + u8 is_ar91xx:1;
  8994. + u8 is_ar724x:1;
  8995. + u8 has_ar8216:1;
  8996. +
  8997. + void (* ddr_flush)(void);
  8998. + void (* set_pll)(int speed);
  8999. +
  9000. + u32 fifo_cfg1;
  9001. + u32 fifo_cfg2;
  9002. + u32 fifo_cfg3;
  9003. +};
  9004. +
  9005. +struct ag71xx_mdio_platform_data {
  9006. + u32 phy_mask;
  9007. + int is_ar7240;
  9008. +};
  9009. +
  9010. +struct ar71xx_ehci_platform_data {
  9011. + u8 is_ar91xx;
  9012. +};
  9013. +
  9014. +struct ar71xx_spi_platform_data {
  9015. + unsigned bus_num;
  9016. + unsigned num_chipselect;
  9017. + u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on);
  9018. +};
  9019. +
  9020. +#define AR71XX_SPI_CS_INACTIVE 0
  9021. +#define AR71XX_SPI_CS_ACTIVE 1
  9022. +
  9023. +#endif /* __ASM_MACH_AR71XX_PLATFORM_H */
  9024. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h
  9025. --- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100
  9026. +++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-05-27 14:36:51.000000000 +0200
  9027. @@ -0,0 +1,25 @@
  9028. +/*
  9029. + * This file is subject to the terms and conditions of the GNU General Public
  9030. + * License. See the file "COPYING" in the main directory of this archive
  9031. + * for more details.
  9032. + *
  9033. + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  9034. + */
  9035. +#ifndef __ASM_MACH_AR71XX_WAR_H
  9036. +#define __ASM_MACH_AR71XX_WAR_H
  9037. +
  9038. +#define R4600_V1_INDEX_ICACHEOP_WAR 0
  9039. +#define R4600_V1_HIT_CACHEOP_WAR 0
  9040. +#define R4600_V2_HIT_CACHEOP_WAR 0
  9041. +#define R5432_CP0_INTERRUPT_WAR 0
  9042. +#define BCM1250_M3_WAR 0
  9043. +#define SIBYTE_1956_WAR 0
  9044. +#define MIPS4K_ICACHE_REFILL_WAR 0
  9045. +#define MIPS_CACHE_SYNC_WAR 0
  9046. +#define TX49XX_ICACHE_INDEX_INV_WAR 0
  9047. +#define RM9000_CDEX_SMP_WAR 0
  9048. +#define ICACHE_REFILLS_WORKAROUND_WAR 0
  9049. +#define R10000_LLSC_WAR 0
  9050. +#define MIPS34K_MISSED_ITLB_WAR 0
  9051. +
  9052. +#endif /* __ASM_MACH_AR71XX_WAR_H */
  9053. diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h
  9054. --- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200
  9055. +++ linux-2.6.39/arch/mips/include/asm/time.h 2011-05-27 14:36:51.000000000 +0200
  9056. @@ -52,6 +52,7 @@
  9057. */
  9058. #ifdef CONFIG_CEVT_R4K_LIB
  9059. extern unsigned int __weak get_c0_compare_int(void);
  9060. +extern unsigned int __weak get_c0_compare_irq(void);
  9061. extern int r4k_clockevent_init(void);
  9062. #endif
  9063. diff -Nur linux-2.6.39.orig/arch/mips/kernel/Makefile linux-2.6.39/arch/mips/kernel/Makefile
  9064. --- linux-2.6.39.orig/arch/mips/kernel/Makefile 2011-05-19 06:06:34.000000000 +0200
  9065. +++ linux-2.6.39/arch/mips/kernel/Makefile 2011-05-27 14:36:51.000000000 +0200
  9066. @@ -94,6 +94,7 @@
  9067. obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
  9068. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  9069. +obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
  9070. obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
  9071. obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
  9072. diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c
  9073. --- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200
  9074. +++ linux-2.6.39/arch/mips/kernel/traps.c 2011-05-27 14:36:51.000000000 +0200
  9075. @@ -46,6 +46,7 @@
  9076. #include <asm/ptrace.h>
  9077. #include <asm/sections.h>
  9078. #include <asm/system.h>
  9079. +#include <asm/time.h>
  9080. #include <asm/tlbdebug.h>
  9081. #include <asm/traps.h>
  9082. #include <asm/uaccess.h>
  9083. @@ -1576,6 +1577,8 @@
  9084. if (cpu_has_mips_r2) {
  9085. cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
  9086. cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
  9087. + if (get_c0_compare_irq)
  9088. + cp0_compare_irq = get_c0_compare_irq();
  9089. cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
  9090. if (cp0_perfcount_irq == cp0_compare_irq)
  9091. cp0_perfcount_irq = -1;
  9092. diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile
  9093. --- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200
  9094. +++ linux-2.6.39/arch/mips/pci/Makefile 2011-05-27 14:36:51.000000000 +0200
  9095. @@ -18,6 +18,7 @@
  9096. obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
  9097. obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
  9098. ops-bcm63xx.o
  9099. +obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o
  9100. #
  9101. # These are still pretty much in the old state, watch, go blind.
  9102. diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c
  9103. --- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  9104. +++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-06-01 14:02:22.000000000 +0200
  9105. @@ -0,0 +1,408 @@
  9106. +/*
  9107. + * Atheros AR71xx PCI host controller driver
  9108. + *
  9109. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  9110. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  9111. + *
  9112. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9113. + *
  9114. + * This program is free software; you can redistribute it and/or modify it
  9115. + * under the terms of the GNU General Public License version 2 as published
  9116. + * by the Free Software Foundation.
  9117. + */
  9118. +
  9119. +#include <linux/resource.h>
  9120. +#include <linux/types.h>
  9121. +#include <linux/delay.h>
  9122. +#include <linux/bitops.h>
  9123. +#include <linux/pci.h>
  9124. +#include <linux/pci_regs.h>
  9125. +#include <linux/interrupt.h>
  9126. +
  9127. +#include <asm/mach-ar71xx/ar71xx.h>
  9128. +#include <asm/mach-ar71xx/pci.h>
  9129. +
  9130. +#undef DEBUG
  9131. +#ifdef DEBUG
  9132. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  9133. +#else
  9134. +#define DBG(fmt, args...)
  9135. +#endif
  9136. +
  9137. +#define AR71XX_PCI_DELAY 100 /* msecs */
  9138. +
  9139. +#if 0
  9140. +#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START
  9141. +#else
  9142. +#define PCI_IDSEL_BASE 0
  9143. +#endif
  9144. +
  9145. +static void __iomem *ar71xx_pcicfg_base;
  9146. +static DEFINE_SPINLOCK(ar71xx_pci_lock);
  9147. +static int ar71xx_pci_fixup_enable;
  9148. +
  9149. +static inline void ar71xx_pci_delay(void)
  9150. +{
  9151. + mdelay(AR71XX_PCI_DELAY);
  9152. +}
  9153. +
  9154. +/* Byte lane enable bits */
  9155. +static u8 ble_table[4][4] = {
  9156. + {0x0, 0xf, 0xf, 0xf},
  9157. + {0xe, 0xd, 0xb, 0x7},
  9158. + {0xc, 0xf, 0x3, 0xf},
  9159. + {0xf, 0xf, 0xf, 0xf},
  9160. +};
  9161. +
  9162. +static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
  9163. +{
  9164. + u32 t;
  9165. +
  9166. + t = ble_table[size & 3][where & 3];
  9167. + BUG_ON(t == 0xf);
  9168. + t <<= (local) ? 20 : 4;
  9169. + return t;
  9170. +}
  9171. +
  9172. +static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
  9173. + int where)
  9174. +{
  9175. + u32 ret;
  9176. +
  9177. + if (!bus->number) {
  9178. + /* type 0 */
  9179. + ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn)))
  9180. + | (PCI_FUNC(devfn) << 8) | (where & ~3);
  9181. + } else {
  9182. + /* type 1 */
  9183. + ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11)
  9184. + | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
  9185. + }
  9186. +
  9187. + return ret;
  9188. +}
  9189. +
  9190. +int ar71xx_pci_be_handler(int is_fixup)
  9191. +{
  9192. + void __iomem *base = ar71xx_pcicfg_base;
  9193. + u32 pci_err;
  9194. + u32 ahb_err;
  9195. +
  9196. + pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3;
  9197. + if (pci_err) {
  9198. + if (!is_fixup)
  9199. + printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n",
  9200. + pci_err,
  9201. + __raw_readl(base + PCI_REG_PCI_ERR_ADDR));
  9202. +
  9203. + __raw_writel(pci_err, base + PCI_REG_PCI_ERR);
  9204. + }
  9205. +
  9206. + ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1;
  9207. + if (ahb_err) {
  9208. + if (!is_fixup)
  9209. + printk(KERN_ALERT "AHB error at AHB address 0x%x\n",
  9210. + __raw_readl(base + PCI_REG_AHB_ERR_ADDR));
  9211. +
  9212. + __raw_writel(ahb_err, base + PCI_REG_AHB_ERR);
  9213. + }
  9214. +
  9215. + return ((ahb_err | pci_err) ? 1 : 0);
  9216. +}
  9217. +
  9218. +static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
  9219. + unsigned int devfn, int where, int size, u32 cmd)
  9220. +{
  9221. + void __iomem *base = ar71xx_pcicfg_base;
  9222. + u32 addr;
  9223. +
  9224. + addr = ar71xx_pci_bus_addr(bus, devfn, where);
  9225. +
  9226. + DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n",
  9227. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9228. + where, size, addr);
  9229. +
  9230. + __raw_writel(addr, base + PCI_REG_CFG_AD);
  9231. + __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
  9232. + base + PCI_REG_CFG_CBE);
  9233. +
  9234. + return ar71xx_pci_be_handler(1);
  9235. +}
  9236. +
  9237. +static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9238. + int where, int size, u32 *value)
  9239. +{
  9240. + void __iomem *base = ar71xx_pcicfg_base;
  9241. + static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
  9242. + unsigned long flags;
  9243. + u32 data;
  9244. + int ret;
  9245. +
  9246. + ret = PCIBIOS_SUCCESSFUL;
  9247. +
  9248. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number,
  9249. + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
  9250. +
  9251. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9252. +
  9253. + if (bus->number == 0 && devfn == 0) {
  9254. + u32 t;
  9255. +
  9256. + t = PCI_CRP_CMD_READ | (where & ~3);
  9257. +
  9258. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9259. + data = __raw_readl(base + PCI_REG_CRP_RDDATA);
  9260. +
  9261. + DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data);
  9262. +
  9263. + } else {
  9264. + int err;
  9265. +
  9266. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9267. + PCI_CFG_CMD_READ);
  9268. +
  9269. + if (err == 0) {
  9270. + data = __raw_readl(base + PCI_REG_CFG_RDDATA);
  9271. + } else {
  9272. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9273. + data = ~0;
  9274. + }
  9275. + }
  9276. +
  9277. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9278. +
  9279. + DBG("PCI: read config: data=%08x raw=%08x\n",
  9280. + (data >> (8 * (where & 3))) & mask[size & 7], data);
  9281. +
  9282. + *value = (data >> (8 * (where & 3))) & mask[size & 7];
  9283. +
  9284. + return ret;
  9285. +}
  9286. +
  9287. +static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9288. + int where, int size, u32 value)
  9289. +{
  9290. + void __iomem *base = ar71xx_pcicfg_base;
  9291. + unsigned long flags;
  9292. + int ret;
  9293. +
  9294. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n",
  9295. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9296. + where, size, value);
  9297. +
  9298. + value = value << (8 * (where & 3));
  9299. + ret = PCIBIOS_SUCCESSFUL;
  9300. +
  9301. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9302. + if (bus->number == 0 && devfn == 0) {
  9303. + u32 t;
  9304. +
  9305. + t = PCI_CRP_CMD_WRITE | (where & ~3);
  9306. + t |= ar71xx_pci_get_ble(where, size, 1);
  9307. +
  9308. + DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value);
  9309. +
  9310. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9311. + __raw_writel(value, base + PCI_REG_CRP_WRDATA);
  9312. + } else {
  9313. + int err;
  9314. +
  9315. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9316. + PCI_CFG_CMD_WRITE);
  9317. +
  9318. + if (err == 0)
  9319. + __raw_writel(value, base + PCI_REG_CFG_WRDATA);
  9320. + else
  9321. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9322. + }
  9323. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9324. +
  9325. + return ret;
  9326. +}
  9327. +
  9328. +static void ar71xx_pci_fixup(struct pci_dev *dev)
  9329. +{
  9330. + u32 t;
  9331. +
  9332. + if (!ar71xx_pci_fixup_enable)
  9333. + return;
  9334. +
  9335. + if (dev->bus->number != 0 || dev->devfn != 0)
  9336. + return;
  9337. +
  9338. + DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev),
  9339. + dev->vendor, dev->device);
  9340. +
  9341. + /* setup COMMAND register */
  9342. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
  9343. + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
  9344. +
  9345. + pci_write_config_word(dev, PCI_COMMAND, t);
  9346. +}
  9347. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup);
  9348. +
  9349. +int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9350. + uint8_t pin)
  9351. +{
  9352. + int irq = -1;
  9353. + int i;
  9354. +
  9355. + slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE;
  9356. +
  9357. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9358. + struct ar71xx_pci_irq *entry;
  9359. +
  9360. + entry = &ar71xx_pci_irq_map[i];
  9361. + if (entry->slot == slot && entry->pin == pin) {
  9362. + irq = entry->irq;
  9363. + break;
  9364. + }
  9365. + }
  9366. +
  9367. + if (irq < 0) {
  9368. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9369. + pin, pci_name((struct pci_dev *)dev));
  9370. + } else {
  9371. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9372. + irq, pin, pci_name((struct pci_dev *)dev));
  9373. + }
  9374. +
  9375. + return irq;
  9376. +}
  9377. +
  9378. +static struct pci_ops ar71xx_pci_ops = {
  9379. + .read = ar71xx_pci_read_config,
  9380. + .write = ar71xx_pci_write_config,
  9381. +};
  9382. +
  9383. +static struct resource ar71xx_pci_io_resource = {
  9384. + .name = "PCI IO space",
  9385. + .start = 0,
  9386. + .end = 0,
  9387. + .flags = IORESOURCE_IO,
  9388. +};
  9389. +
  9390. +static struct resource ar71xx_pci_mem_resource = {
  9391. + .name = "PCI memory space",
  9392. + .start = AR71XX_PCI_MEM_BASE,
  9393. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9394. + .flags = IORESOURCE_MEM
  9395. +};
  9396. +
  9397. +static struct pci_controller ar71xx_pci_controller = {
  9398. + .pci_ops = &ar71xx_pci_ops,
  9399. + .mem_resource = &ar71xx_pci_mem_resource,
  9400. + .io_resource = &ar71xx_pci_io_resource,
  9401. +};
  9402. +
  9403. +static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  9404. +{
  9405. + void __iomem *base = ar71xx_reset_base;
  9406. + u32 pending;
  9407. +
  9408. + pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
  9409. + __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9410. +
  9411. + if (pending & PCI_INT_DEV0)
  9412. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  9413. +
  9414. + else if (pending & PCI_INT_DEV1)
  9415. + generic_handle_irq(AR71XX_PCI_IRQ_DEV1);
  9416. +
  9417. + else if (pending & PCI_INT_DEV2)
  9418. + generic_handle_irq(AR71XX_PCI_IRQ_DEV2);
  9419. +
  9420. + else if (pending & PCI_INT_CORE)
  9421. + generic_handle_irq(AR71XX_PCI_IRQ_CORE);
  9422. +
  9423. + else
  9424. + spurious_interrupt();
  9425. +}
  9426. +
  9427. +static void ar71xx_pci_irq_unmask(struct irq_data *d)
  9428. +{
  9429. + void __iomem *base = ar71xx_reset_base;
  9430. + u32 t;
  9431. +
  9432. + d->irq -= AR71XX_PCI_IRQ_BASE;
  9433. +
  9434. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9435. + __raw_writel(t | (1 << d->irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9436. +
  9437. + /* flush write */
  9438. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9439. +}
  9440. +
  9441. +static void ar71xx_pci_irq_mask(struct irq_data *d)
  9442. +{
  9443. + void __iomem *base = ar71xx_reset_base;
  9444. + u32 t;
  9445. +
  9446. + d->irq -= AR71XX_PCI_IRQ_BASE;
  9447. +
  9448. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9449. + __raw_writel(t & ~(1 << d->irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9450. +
  9451. + /* flush write */
  9452. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9453. +}
  9454. +
  9455. +static struct irq_chip ar71xx_pci_irq_chip = {
  9456. + .name = "AR71XX PCI ",
  9457. + .irq_mask = ar71xx_pci_irq_mask,
  9458. + .irq_unmask = ar71xx_pci_irq_unmask,
  9459. + .irq_mask_ack = ar71xx_pci_irq_mask,
  9460. +};
  9461. +
  9462. +static void __init ar71xx_pci_irq_init(void)
  9463. +{
  9464. + void __iomem *base = ar71xx_reset_base;
  9465. + int i;
  9466. +
  9467. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9468. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
  9469. +
  9470. + for (i = AR71XX_PCI_IRQ_BASE;
  9471. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  9472. + irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
  9473. + handle_level_irq);
  9474. + }
  9475. +
  9476. + irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
  9477. +}
  9478. +
  9479. +int __init ar71xx_pcibios_init(void)
  9480. +{
  9481. + void __iomem *ddr_base = ar71xx_ddr_base;
  9482. +
  9483. + ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9484. + ar71xx_pci_delay();
  9485. +
  9486. + ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9487. + ar71xx_pci_delay();
  9488. +
  9489. + ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE,
  9490. + AR71XX_PCI_CFG_SIZE);
  9491. + if (ar71xx_pcicfg_base == NULL)
  9492. + return -ENOMEM;
  9493. +
  9494. + __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
  9495. + __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
  9496. + __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
  9497. + __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
  9498. + __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
  9499. + __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
  9500. + __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
  9501. + __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
  9502. +
  9503. + ar71xx_pci_delay();
  9504. +
  9505. + /* clear bus errors */
  9506. + (void)ar71xx_pci_be_handler(1);
  9507. +
  9508. + ar71xx_pci_fixup_enable = 1;
  9509. + ar71xx_pci_irq_init();
  9510. + register_pci_controller(&ar71xx_pci_controller);
  9511. +
  9512. + return 0;
  9513. +}
  9514. diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c
  9515. --- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100
  9516. +++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-06-01 14:02:22.000000000 +0200
  9517. @@ -0,0 +1,394 @@
  9518. +/*
  9519. + * Atheros AR724x PCI host controller driver
  9520. + *
  9521. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  9522. + *
  9523. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9524. + *
  9525. + * This program is free software; you can redistribute it and/or modify it
  9526. + * under the terms of the GNU General Public License version 2 as published
  9527. + * by the Free Software Foundation.
  9528. + */
  9529. +
  9530. +#include <linux/resource.h>
  9531. +#include <linux/types.h>
  9532. +#include <linux/delay.h>
  9533. +#include <linux/bitops.h>
  9534. +#include <linux/pci.h>
  9535. +#include <linux/pci_regs.h>
  9536. +#include <linux/interrupt.h>
  9537. +
  9538. +#include <asm/mach-ar71xx/ar71xx.h>
  9539. +#include <asm/mach-ar71xx/pci.h>
  9540. +
  9541. +#undef DEBUG
  9542. +#ifdef DEBUG
  9543. +#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args)
  9544. +#else
  9545. +#define DBG(fmt, args...)
  9546. +#endif
  9547. +
  9548. +static void __iomem *ar724x_pci_localcfg_base;
  9549. +static void __iomem *ar724x_pci_devcfg_base;
  9550. +static void __iomem *ar724x_pci_ctrl_base;
  9551. +static int ar724x_pci_fixup_enable;
  9552. +
  9553. +static DEFINE_SPINLOCK(ar724x_pci_lock);
  9554. +
  9555. +static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value)
  9556. +{
  9557. + unsigned long flags;
  9558. + u32 data;
  9559. +
  9560. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9561. + data = __raw_readl(base + (where & ~3));
  9562. +
  9563. + switch (size) {
  9564. + case 1:
  9565. + if (where & 1)
  9566. + data >>= 8;
  9567. + if (where & 2)
  9568. + data >>= 16;
  9569. + data &= 0xFF;
  9570. + break;
  9571. + case 2:
  9572. + if (where & 2)
  9573. + data >>= 16;
  9574. + data &= 0xFFFF;
  9575. + break;
  9576. + }
  9577. +
  9578. + *value = data;
  9579. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9580. +}
  9581. +
  9582. +static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value)
  9583. +{
  9584. + unsigned long flags;
  9585. + u32 data;
  9586. + int s;
  9587. +
  9588. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9589. + data = __raw_readl(base + (where & ~3));
  9590. +
  9591. + switch (size) {
  9592. + case 1:
  9593. + s = ((where & 3) << 3);
  9594. + data &= ~(0xFF << s);
  9595. + data |= ((value & 0xFF) << s);
  9596. + break;
  9597. + case 2:
  9598. + s = ((where & 2) << 3);
  9599. + data &= ~(0xFFFF << s);
  9600. + data |= ((value & 0xFFFF) << s);
  9601. + break;
  9602. + case 4:
  9603. + data = value;
  9604. + break;
  9605. + }
  9606. +
  9607. + __raw_writel(data, base + (where & ~3));
  9608. + /* flush write */
  9609. + (void)__raw_readl(base + (where & ~3));
  9610. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9611. +}
  9612. +
  9613. +static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9614. + int where, int size, u32 *value)
  9615. +{
  9616. +
  9617. + if (bus->number != 0 || devfn != 0)
  9618. + return PCIBIOS_DEVICE_NOT_FOUND;
  9619. +
  9620. + ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value);
  9621. +
  9622. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9623. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9624. + where, size, *value);
  9625. +
  9626. + /*
  9627. + * WAR for BAR issue - We are unable to access the PCI device space
  9628. + * if we set the BAR with proper base address
  9629. + */
  9630. + if ((where == 0x10) && (size == 4)) {
  9631. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9632. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0xffff);
  9633. + else
  9634. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0x1000ffff);
  9635. + }
  9636. +
  9637. + return PCIBIOS_SUCCESSFUL;
  9638. +}
  9639. +
  9640. +static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9641. + int where, int size, u32 value)
  9642. +{
  9643. + if (bus->number != 0 || devfn != 0)
  9644. + return PCIBIOS_DEVICE_NOT_FOUND;
  9645. +
  9646. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9647. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9648. + where, size, value);
  9649. +
  9650. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value);
  9651. +
  9652. + return PCIBIOS_SUCCESSFUL;
  9653. +}
  9654. +
  9655. +static void ar724x_pci_fixup(struct pci_dev *dev)
  9656. +{
  9657. + u16 cmd;
  9658. +
  9659. + if (!ar724x_pci_fixup_enable)
  9660. + return;
  9661. +
  9662. + if (dev->bus->number != 0 || dev->devfn != 0)
  9663. + return;
  9664. +
  9665. + /* setup COMMAND register */
  9666. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  9667. + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
  9668. + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
  9669. + PCI_COMMAND_FAST_BACK;
  9670. +
  9671. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  9672. +}
  9673. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup);
  9674. +
  9675. +int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9676. + uint8_t pin)
  9677. +{
  9678. + int irq = -1;
  9679. + int i;
  9680. +
  9681. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9682. + struct ar71xx_pci_irq *entry;
  9683. + entry = &ar71xx_pci_irq_map[i];
  9684. +
  9685. + if (entry->slot == slot && entry->pin == pin) {
  9686. + irq = entry->irq;
  9687. + break;
  9688. + }
  9689. + }
  9690. +
  9691. + if (irq < 0)
  9692. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9693. + pin, pci_name((struct pci_dev *)dev));
  9694. + else
  9695. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9696. + irq, pin, pci_name((struct pci_dev *)dev));
  9697. +
  9698. + return irq;
  9699. +}
  9700. +
  9701. +static struct pci_ops ar724x_pci_ops = {
  9702. + .read = ar724x_pci_read_config,
  9703. + .write = ar724x_pci_write_config,
  9704. +};
  9705. +
  9706. +static struct resource ar724x_pci_io_resource = {
  9707. + .name = "PCI IO space",
  9708. + .start = 0,
  9709. + .end = 0,
  9710. + .flags = IORESOURCE_IO,
  9711. +};
  9712. +
  9713. +static struct resource ar724x_pci_mem_resource = {
  9714. + .name = "PCI memory space",
  9715. + .start = AR71XX_PCI_MEM_BASE,
  9716. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9717. + .flags = IORESOURCE_MEM
  9718. +};
  9719. +
  9720. +static struct pci_controller ar724x_pci_controller = {
  9721. + .pci_ops = &ar724x_pci_ops,
  9722. + .mem_resource = &ar724x_pci_mem_resource,
  9723. + .io_resource = &ar724x_pci_io_resource,
  9724. +};
  9725. +
  9726. +static void __init ar724x_pci_reset(void)
  9727. +{
  9728. + ar71xx_device_stop(AR724X_RESET_PCIE);
  9729. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY);
  9730. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL);
  9731. + udelay(100);
  9732. +
  9733. + ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL);
  9734. + udelay(100);
  9735. + ar71xx_device_start(AR724X_RESET_PCIE_PHY);
  9736. + ar71xx_device_start(AR724X_RESET_PCIE);
  9737. +}
  9738. +
  9739. +static int __init ar724x_pci_setup(void)
  9740. +{
  9741. + void __iomem *base = ar724x_pci_ctrl_base;
  9742. + u32 t;
  9743. +
  9744. + /* setup COMMAND register */
  9745. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE |
  9746. + PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK;
  9747. +
  9748. + ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t);
  9749. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000);
  9750. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000);
  9751. +
  9752. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9753. + if (t != 0x7) {
  9754. + udelay(100000);
  9755. + __raw_writel(0, base + AR724X_PCI_REG_RESET);
  9756. + udelay(100);
  9757. + __raw_writel(4, base + AR724X_PCI_REG_RESET);
  9758. + udelay(100000);
  9759. + }
  9760. +
  9761. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9762. + t = AR724X_PCI_APP_LTSSM_ENABLE;
  9763. + else
  9764. + t = 0x1ffc1;
  9765. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  9766. + /* flush write */
  9767. + (void) __raw_readl(base + AR724X_PCI_REG_APP);
  9768. + udelay(1000);
  9769. +
  9770. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9771. + if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) {
  9772. + printk(KERN_WARNING "PCI: no PCIe module found\n");
  9773. + return -ENODEV;
  9774. + }
  9775. +
  9776. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  9777. + t = __raw_readl(base + AR724X_PCI_REG_APP);
  9778. + t |= BIT(16);
  9779. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  9780. + }
  9781. +
  9782. + return 0;
  9783. +}
  9784. +
  9785. +static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  9786. +{
  9787. + void __iomem *base = ar724x_pci_ctrl_base;
  9788. + u32 pending;
  9789. +
  9790. + pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
  9791. + __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  9792. +
  9793. + if (pending & AR724X_PCI_INT_DEV0)
  9794. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  9795. +
  9796. + else
  9797. + spurious_interrupt();
  9798. +}
  9799. +
  9800. +static void ar724x_pci_irq_unmask(struct irq_data *d)
  9801. +{
  9802. + void __iomem *base = ar724x_pci_ctrl_base;
  9803. + u32 t;
  9804. +
  9805. + switch (d->irq) {
  9806. + case AR71XX_PCI_IRQ_DEV0:
  9807. + d->irq -= AR71XX_PCI_IRQ_BASE;
  9808. +
  9809. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  9810. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  9811. + base + AR724X_PCI_REG_INT_MASK);
  9812. + /* flush write */
  9813. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  9814. + }
  9815. +}
  9816. +
  9817. +static void ar724x_pci_irq_mask(struct irq_data *d)
  9818. +{
  9819. + void __iomem *base = ar724x_pci_ctrl_base;
  9820. + u32 t;
  9821. +
  9822. + switch (d->irq) {
  9823. + case AR71XX_PCI_IRQ_DEV0:
  9824. + d->irq -= AR71XX_PCI_IRQ_BASE;
  9825. +
  9826. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  9827. + __raw_writel(t & ~AR724X_PCI_INT_DEV0,
  9828. + base + AR724X_PCI_REG_INT_MASK);
  9829. +
  9830. + /* flush write */
  9831. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  9832. +
  9833. + t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  9834. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  9835. + base + AR724X_PCI_REG_INT_STATUS);
  9836. +
  9837. + /* flush write */
  9838. + (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  9839. + }
  9840. +}
  9841. +
  9842. +static struct irq_chip ar724x_pci_irq_chip = {
  9843. + .name = "AR724X PCI ",
  9844. + .irq_mask = ar724x_pci_irq_mask,
  9845. + .irq_unmask = ar724x_pci_irq_unmask,
  9846. + .irq_mask_ack = ar724x_pci_irq_mask,
  9847. +};
  9848. +
  9849. +static void __init ar724x_pci_irq_init(void)
  9850. +{
  9851. + void __iomem *base = ar724x_pci_ctrl_base;
  9852. + u32 t;
  9853. + int i;
  9854. +
  9855. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  9856. + if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY |
  9857. + AR724X_RESET_PCIE_PHY_SERIAL)) {
  9858. + return;
  9859. + }
  9860. +
  9861. + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
  9862. + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
  9863. +
  9864. + for (i = AR71XX_PCI_IRQ_BASE;
  9865. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  9866. + irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
  9867. + handle_level_irq);
  9868. + }
  9869. +
  9870. + irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler);
  9871. +}
  9872. +
  9873. +int __init ar724x_pcibios_init(void)
  9874. +{
  9875. + int ret = -ENOMEM;
  9876. +
  9877. + ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE,
  9878. + AR724X_PCI_CRP_SIZE);
  9879. + if (ar724x_pci_localcfg_base == NULL)
  9880. + goto err;
  9881. +
  9882. + ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE,
  9883. + AR724X_PCI_CFG_SIZE);
  9884. + if (ar724x_pci_devcfg_base == NULL)
  9885. + goto err_unmap_localcfg;
  9886. +
  9887. + ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE,
  9888. + AR724X_PCI_CTRL_SIZE);
  9889. + if (ar724x_pci_ctrl_base == NULL)
  9890. + goto err_unmap_devcfg;
  9891. +
  9892. + ar724x_pci_reset();
  9893. + ret = ar724x_pci_setup();
  9894. + if (ret)
  9895. + goto err_unmap_ctrl;
  9896. +
  9897. + ar724x_pci_fixup_enable = 1;
  9898. + ar724x_pci_irq_init();
  9899. + register_pci_controller(&ar724x_pci_controller);
  9900. +
  9901. + return 0;
  9902. +
  9903. + err_unmap_ctrl:
  9904. + iounmap(ar724x_pci_ctrl_base);
  9905. + err_unmap_devcfg:
  9906. + iounmap(ar724x_pci_devcfg_base);
  9907. + err_unmap_localcfg:
  9908. + iounmap(ar724x_pci_localcfg_base);
  9909. + err:
  9910. + return ret;
  9911. +}
  9912. diff -Nur linux-2.6.39.orig/drivers/char/Kconfig linux-2.6.39/drivers/char/Kconfig
  9913. --- linux-2.6.39.orig/drivers/char/Kconfig 2011-05-19 06:06:34.000000000 +0200
  9914. +++ linux-2.6.39/drivers/char/Kconfig 2011-05-27 14:36:51.000000000 +0200
  9915. @@ -511,6 +511,14 @@
  9916. pc8736x_gpio drivers. If those drivers are built as
  9917. modules, this one will be too, named nsc_gpio
  9918. +config GPIO_DEVICE
  9919. + tristate "GPIO device support"
  9920. + depends on GENERIC_GPIO
  9921. + help
  9922. + Say Y to enable Linux GPIO device support. This allows control of
  9923. + GPIO pins using a character device
  9924. +
  9925. +
  9926. config RAW_DRIVER
  9927. tristate "RAW driver (/dev/raw/rawN)"
  9928. depends on BLOCK
  9929. diff -Nur linux-2.6.39.orig/drivers/char/Makefile linux-2.6.39/drivers/char/Makefile
  9930. --- linux-2.6.39.orig/drivers/char/Makefile 2011-05-19 06:06:34.000000000 +0200
  9931. +++ linux-2.6.39/drivers/char/Makefile 2011-05-27 14:36:51.000000000 +0200
  9932. @@ -47,6 +47,7 @@
  9933. obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
  9934. obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
  9935. obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
  9936. +obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o
  9937. obj-$(CONFIG_GPIO_TB0219) += tb0219.o
  9938. obj-$(CONFIG_TELCLOCK) += tlclk.o
  9939. diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c
  9940. --- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100
  9941. +++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-05-27 14:36:51.000000000 +0200
  9942. @@ -0,0 +1,246 @@
  9943. +/*
  9944. + * NXP 74HC153 - Dual 4-input multiplexer GPIO driver
  9945. + *
  9946. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  9947. + *
  9948. + * This program is free software; you can redistribute it and/or modify
  9949. + * it under the terms of the GNU General Public License version 2 as
  9950. + * published by the Free Software Foundation.
  9951. + */
  9952. +
  9953. +#include <linux/module.h>
  9954. +#include <linux/init.h>
  9955. +#include <linux/gpio.h>
  9956. +#include <linux/platform_device.h>
  9957. +#include <linux/nxp_74hc153.h>
  9958. +
  9959. +#define NXP_74HC153_NUM_GPIOS 8
  9960. +#define NXP_74HC153_S0_MASK 0x1
  9961. +#define NXP_74HC153_S1_MASK 0x2
  9962. +#define NXP_74HC153_BANK_MASK 0x4
  9963. +
  9964. +struct nxp_74hc153_chip {
  9965. + struct device *parent;
  9966. + struct gpio_chip gpio_chip;
  9967. + struct mutex lock;
  9968. +};
  9969. +
  9970. +static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc)
  9971. +{
  9972. + return container_of(gc, struct nxp_74hc153_chip, gpio_chip);
  9973. +}
  9974. +
  9975. +static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset)
  9976. +{
  9977. + return 0;
  9978. +}
  9979. +
  9980. +static int nxp_74hc153_direction_output(struct gpio_chip *gc,
  9981. + unsigned offset, int val)
  9982. +{
  9983. + return -EINVAL;
  9984. +}
  9985. +
  9986. +static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset)
  9987. +{
  9988. + struct nxp_74hc153_chip *nxp;
  9989. + struct nxp_74hc153_platform_data *pdata;
  9990. + unsigned s0;
  9991. + unsigned s1;
  9992. + unsigned pin;
  9993. + int ret;
  9994. +
  9995. + nxp = gpio_to_nxp(gc);
  9996. + pdata = nxp->parent->platform_data;
  9997. +
  9998. + s0 = !!(offset & NXP_74HC153_S0_MASK);
  9999. + s1 = !!(offset & NXP_74HC153_S1_MASK);
  10000. + pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y
  10001. + : pdata->gpio_pin_1y;
  10002. +
  10003. + mutex_lock(&nxp->lock);
  10004. + gpio_set_value(pdata->gpio_pin_s0, s0);
  10005. + gpio_set_value(pdata->gpio_pin_s1, s1);
  10006. + ret = gpio_get_value(pin);
  10007. + mutex_unlock(&nxp->lock);
  10008. +
  10009. + return ret;
  10010. +}
  10011. +
  10012. +static void nxp_74hc153_set_value(struct gpio_chip *gc,
  10013. + unsigned offset, int val)
  10014. +{
  10015. + /* not supported */
  10016. +}
  10017. +
  10018. +static int __devinit nxp_74hc153_probe(struct platform_device *pdev)
  10019. +{
  10020. + struct nxp_74hc153_platform_data *pdata;
  10021. + struct nxp_74hc153_chip *nxp;
  10022. + struct gpio_chip *gc;
  10023. + int err;
  10024. +
  10025. + pdata = pdev->dev.platform_data;
  10026. + if (pdata == NULL) {
  10027. + dev_dbg(&pdev->dev, "no platform data specified\n");
  10028. + return -EINVAL;
  10029. + }
  10030. +
  10031. + nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL);
  10032. + if (nxp == NULL) {
  10033. + dev_err(&pdev->dev, "no memory for private data\n");
  10034. + return -ENOMEM;
  10035. + }
  10036. +
  10037. + err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev));
  10038. + if (err) {
  10039. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10040. + pdata->gpio_pin_s0, err);
  10041. + goto err_free_nxp;
  10042. + }
  10043. +
  10044. + err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev));
  10045. + if (err) {
  10046. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10047. + pdata->gpio_pin_s1, err);
  10048. + goto err_free_s0;
  10049. + }
  10050. +
  10051. + err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev));
  10052. + if (err) {
  10053. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10054. + pdata->gpio_pin_1y, err);
  10055. + goto err_free_s1;
  10056. + }
  10057. +
  10058. + err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev));
  10059. + if (err) {
  10060. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10061. + pdata->gpio_pin_2y, err);
  10062. + goto err_free_1y;
  10063. + }
  10064. +
  10065. + err = gpio_direction_output(pdata->gpio_pin_s0, 0);
  10066. + if (err) {
  10067. + dev_err(&pdev->dev,
  10068. + "unable to set direction of gpio %u, err=%d\n",
  10069. + pdata->gpio_pin_s0, err);
  10070. + goto err_free_2y;
  10071. + }
  10072. +
  10073. + err = gpio_direction_output(pdata->gpio_pin_s1, 0);
  10074. + if (err) {
  10075. + dev_err(&pdev->dev,
  10076. + "unable to set direction of gpio %u, err=%d\n",
  10077. + pdata->gpio_pin_s1, err);
  10078. + goto err_free_2y;
  10079. + }
  10080. +
  10081. + err = gpio_direction_input(pdata->gpio_pin_1y);
  10082. + if (err) {
  10083. + dev_err(&pdev->dev,
  10084. + "unable to set direction of gpio %u, err=%d\n",
  10085. + pdata->gpio_pin_1y, err);
  10086. + goto err_free_2y;
  10087. + }
  10088. +
  10089. + err = gpio_direction_input(pdata->gpio_pin_2y);
  10090. + if (err) {
  10091. + dev_err(&pdev->dev,
  10092. + "unable to set direction of gpio %u, err=%d\n",
  10093. + pdata->gpio_pin_2y, err);
  10094. + goto err_free_2y;
  10095. + }
  10096. +
  10097. + nxp->parent = &pdev->dev;
  10098. + mutex_init(&nxp->lock);
  10099. +
  10100. + gc = &nxp->gpio_chip;
  10101. +
  10102. + gc->direction_input = nxp_74hc153_direction_input;
  10103. + gc->direction_output = nxp_74hc153_direction_output;
  10104. + gc->get = nxp_74hc153_get_value;
  10105. + gc->set = nxp_74hc153_set_value;
  10106. + gc->can_sleep = 1;
  10107. +
  10108. + gc->base = pdata->gpio_base;
  10109. + gc->ngpio = NXP_74HC153_NUM_GPIOS;
  10110. + gc->label = dev_name(nxp->parent);
  10111. + gc->dev = nxp->parent;
  10112. + gc->owner = THIS_MODULE;
  10113. +
  10114. + err = gpiochip_add(&nxp->gpio_chip);
  10115. + if (err) {
  10116. + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
  10117. + goto err_free_2y;
  10118. + }
  10119. +
  10120. + platform_set_drvdata(pdev, nxp);
  10121. + return 0;
  10122. +
  10123. + err_free_2y:
  10124. + gpio_free(pdata->gpio_pin_2y);
  10125. + err_free_1y:
  10126. + gpio_free(pdata->gpio_pin_1y);
  10127. + err_free_s1:
  10128. + gpio_free(pdata->gpio_pin_s1);
  10129. + err_free_s0:
  10130. + gpio_free(pdata->gpio_pin_s0);
  10131. + err_free_nxp:
  10132. + kfree(nxp);
  10133. + return err;
  10134. +}
  10135. +
  10136. +static int nxp_74hc153_remove(struct platform_device *pdev)
  10137. +{
  10138. + struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev);
  10139. + struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data;
  10140. +
  10141. + if (nxp) {
  10142. + int err;
  10143. +
  10144. + err = gpiochip_remove(&nxp->gpio_chip);
  10145. + if (err) {
  10146. + dev_err(&pdev->dev,
  10147. + "unable to remove gpio chip, err=%d\n",
  10148. + err);
  10149. + return err;
  10150. + }
  10151. +
  10152. + gpio_free(pdata->gpio_pin_2y);
  10153. + gpio_free(pdata->gpio_pin_1y);
  10154. + gpio_free(pdata->gpio_pin_s1);
  10155. + gpio_free(pdata->gpio_pin_s0);
  10156. +
  10157. + kfree(nxp);
  10158. + platform_set_drvdata(pdev, NULL);
  10159. + }
  10160. +
  10161. + return 0;
  10162. +}
  10163. +
  10164. +static struct platform_driver nxp_74hc153_driver = {
  10165. + .probe = nxp_74hc153_probe,
  10166. + .remove = __devexit_p(nxp_74hc153_remove),
  10167. + .driver = {
  10168. + .name = NXP_74HC153_DRIVER_NAME,
  10169. + .owner = THIS_MODULE,
  10170. + },
  10171. +};
  10172. +
  10173. +static int __init nxp_74hc153_init(void)
  10174. +{
  10175. + return platform_driver_register(&nxp_74hc153_driver);
  10176. +}
  10177. +subsys_initcall(nxp_74hc153_init);
  10178. +
  10179. +static void __exit nxp_74hc153_exit(void)
  10180. +{
  10181. + platform_driver_unregister(&nxp_74hc153_driver);
  10182. +}
  10183. +module_exit(nxp_74hc153_exit);
  10184. +
  10185. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10186. +MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153");
  10187. +MODULE_LICENSE("GPL v2");
  10188. +MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME);
  10189. diff -Nur linux-2.6.39.orig/drivers/input/misc/Kconfig linux-2.6.39/drivers/input/misc/Kconfig
  10190. --- linux-2.6.39.orig/drivers/input/misc/Kconfig 2011-05-19 06:06:34.000000000 +0200
  10191. +++ linux-2.6.39/drivers/input/misc/Kconfig 2011-05-27 14:36:51.000000000 +0200
  10192. @@ -467,4 +467,20 @@
  10193. To compile this driver as a module, choose M here: the
  10194. module will be called xen-kbdfront.
  10195. +config INPUT_GPIO_BUTTONS
  10196. + tristate "Polled GPIO buttons interface"
  10197. + depends on GENERIC_GPIO
  10198. + select INPUT_POLLDEV
  10199. + help
  10200. + This driver implements support for buttons connected
  10201. + to GPIO pins of various CPUs (and some other chips).
  10202. +
  10203. + Say Y here if your device has buttons connected
  10204. + directly to such GPIO pins. Your board-specific
  10205. + setup logic must also provide a platform device,
  10206. + with configuration data saying which GPIOs are used.
  10207. +
  10208. + To compile this driver as a module, choose M here: the
  10209. + module will be called gpio-buttons.
  10210. +
  10211. endif
  10212. diff -Nur linux-2.6.39.orig/drivers/input/misc/Makefile linux-2.6.39/drivers/input/misc/Makefile
  10213. --- linux-2.6.39.orig/drivers/input/misc/Makefile 2011-05-19 06:06:34.000000000 +0200
  10214. +++ linux-2.6.39/drivers/input/misc/Makefile 2011-05-27 14:36:51.000000000 +0200
  10215. @@ -44,4 +44,5 @@
  10216. obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
  10217. obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
  10218. obj-$(CONFIG_INPUT_YEALINK) += yealink.o
  10219. +obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o
  10220. diff -Nur linux-2.6.39.orig/drivers/input/misc/gpio_buttons.c linux-2.6.39/drivers/input/misc/gpio_buttons.c
  10221. --- linux-2.6.39.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100
  10222. +++ linux-2.6.39/drivers/input/misc/gpio_buttons.c 2011-05-27 14:36:51.000000000 +0200
  10223. @@ -0,0 +1,216 @@
  10224. +/*
  10225. + * Driver for buttons on GPIO lines not capable of generating interrupts
  10226. + *
  10227. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  10228. + * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
  10229. + *
  10230. + * This file was based on: /drivers/input/misc/cobalt_btns.c
  10231. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  10232. + *
  10233. + * also was based on: /drivers/input/keyboard/gpio_keys.c
  10234. + * Copyright 2005 Phil Blundell
  10235. + *
  10236. + * This program is free software; you can redistribute it and/or modify
  10237. + * it under the terms of the GNU General Public License version 2 as
  10238. + * published by the Free Software Foundation.
  10239. + *
  10240. + */
  10241. +
  10242. +#include <linux/kernel.h>
  10243. +#include <linux/module.h>
  10244. +#include <linux/init.h>
  10245. +#include <linux/slab.h>
  10246. +
  10247. +#include <linux/input.h>
  10248. +#include <linux/input-polldev.h>
  10249. +#include <linux/ioport.h>
  10250. +#include <linux/platform_device.h>
  10251. +
  10252. +#include <linux/gpio_buttons.h>
  10253. +
  10254. +#include <asm/gpio.h>
  10255. +
  10256. +#define DRV_NAME "gpio-buttons"
  10257. +#define DRV_VERSION "0.1.2"
  10258. +#define PFX DRV_NAME ": "
  10259. +
  10260. +struct gpio_button_data {
  10261. + int last_state;
  10262. + int count;
  10263. +};
  10264. +
  10265. +struct gpio_buttons_dev {
  10266. + struct input_polled_dev *poll_dev;
  10267. + struct gpio_buttons_platform_data *pdata;
  10268. + struct gpio_button_data *data;
  10269. +};
  10270. +
  10271. +static void gpio_buttons_poll(struct input_polled_dev *dev)
  10272. +{
  10273. + struct gpio_buttons_dev *bdev = dev->private;
  10274. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10275. + struct input_dev *input = dev->input;
  10276. + int i;
  10277. +
  10278. + for (i = 0; i < bdev->pdata->nbuttons; i++) {
  10279. + struct gpio_button *button = &pdata->buttons[i];
  10280. + unsigned int type = button->type ?: EV_KEY;
  10281. + int state;
  10282. +
  10283. + if (bdev->data[i].count < button->threshold) {
  10284. + bdev->data[i].count++;
  10285. + continue;
  10286. + }
  10287. +
  10288. + state = gpio_get_value(button->gpio) ? 1 : 0;
  10289. + if (state != bdev->data[i].last_state) {
  10290. + input_event(input, type, button->code,
  10291. + !!(state ^ button->active_low));
  10292. + input_sync(input);
  10293. + bdev->data[i].count = 0;
  10294. + bdev->data[i].last_state = state;
  10295. + }
  10296. + }
  10297. +}
  10298. +
  10299. +static int __devinit gpio_buttons_probe(struct platform_device *pdev)
  10300. +{
  10301. + struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data;
  10302. + struct gpio_buttons_dev *bdev;
  10303. + struct input_polled_dev *poll_dev;
  10304. + struct input_dev *input;
  10305. + int error, i;
  10306. +
  10307. + if (!pdata)
  10308. + return -ENXIO;
  10309. +
  10310. + bdev = kzalloc(sizeof(struct gpio_buttons_dev) +
  10311. + sizeof(struct gpio_button_data) * pdata->nbuttons,
  10312. + GFP_KERNEL);
  10313. + if (!bdev) {
  10314. + printk(KERN_ERR DRV_NAME "no memory for device\n");
  10315. + return -ENOMEM;
  10316. + }
  10317. +
  10318. + bdev->data = (struct gpio_button_data *) &bdev[1];
  10319. +
  10320. + poll_dev = input_allocate_polled_device();
  10321. + if (!poll_dev) {
  10322. + printk(KERN_ERR DRV_NAME "no memory for polled device\n");
  10323. + error = -ENOMEM;
  10324. + goto err_free_bdev;
  10325. + }
  10326. +
  10327. + poll_dev->private = bdev;
  10328. + poll_dev->poll = gpio_buttons_poll;
  10329. + poll_dev->poll_interval = pdata->poll_interval;
  10330. +
  10331. + input = poll_dev->input;
  10332. +
  10333. + input->evbit[0] = BIT(EV_KEY);
  10334. + input->name = pdev->name;
  10335. + input->phys = "gpio-buttons/input0";
  10336. + input->dev.parent = &pdev->dev;
  10337. +
  10338. + input->id.bustype = BUS_HOST;
  10339. + input->id.vendor = 0x0001;
  10340. + input->id.product = 0x0001;
  10341. + input->id.version = 0x0100;
  10342. +
  10343. + for (i = 0; i < pdata->nbuttons; i++) {
  10344. + struct gpio_button *button = &pdata->buttons[i];
  10345. + unsigned int gpio = button->gpio;
  10346. + unsigned int type = button->type ?: EV_KEY;
  10347. +
  10348. + error = gpio_request(gpio, button->desc ?
  10349. + button->desc : DRV_NAME);
  10350. + if (error) {
  10351. + printk(KERN_ERR PFX "unable to claim gpio %u, "
  10352. + "error %d\n", gpio, error);
  10353. + goto err_free_gpio;
  10354. + }
  10355. +
  10356. + error = gpio_direction_input(gpio);
  10357. + if (error) {
  10358. + printk(KERN_ERR PFX "unable to set direction on "
  10359. + "gpio %u, error %d\n", gpio, error);
  10360. + goto err_free_gpio;
  10361. + }
  10362. +
  10363. + input_set_capability(input, type, button->code);
  10364. + bdev->data[i].last_state = gpio_get_value(button->gpio) ? 1 : 0;
  10365. + }
  10366. +
  10367. + bdev->poll_dev = poll_dev;
  10368. + bdev->pdata = pdata;
  10369. + platform_set_drvdata(pdev, bdev);
  10370. +
  10371. + error = input_register_polled_device(poll_dev);
  10372. + if (error) {
  10373. + printk(KERN_ERR PFX "unable to register polled device, "
  10374. + "error %d\n", error);
  10375. + goto err_free_gpio;
  10376. + }
  10377. +
  10378. + return 0;
  10379. +
  10380. +err_free_gpio:
  10381. + for (i = i - 1; i >= 0; i--)
  10382. + gpio_free(pdata->buttons[i].gpio);
  10383. +
  10384. + input_free_polled_device(poll_dev);
  10385. +
  10386. +err_free_bdev:
  10387. + kfree(bdev);
  10388. +
  10389. + platform_set_drvdata(pdev, NULL);
  10390. + return error;
  10391. +}
  10392. +
  10393. +static int __devexit gpio_buttons_remove(struct platform_device *pdev)
  10394. +{
  10395. + struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev);
  10396. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10397. + int i;
  10398. +
  10399. + input_unregister_polled_device(bdev->poll_dev);
  10400. +
  10401. + for (i = 0; i < pdata->nbuttons; i++)
  10402. + gpio_free(pdata->buttons[i].gpio);
  10403. +
  10404. + input_free_polled_device(bdev->poll_dev);
  10405. +
  10406. + kfree(bdev);
  10407. + platform_set_drvdata(pdev, NULL);
  10408. +
  10409. + return 0;
  10410. +}
  10411. +
  10412. +static struct platform_driver gpio_buttons_driver = {
  10413. + .probe = gpio_buttons_probe,
  10414. + .remove = __devexit_p(gpio_buttons_remove),
  10415. + .driver = {
  10416. + .name = DRV_NAME,
  10417. + .owner = THIS_MODULE,
  10418. + },
  10419. +};
  10420. +
  10421. +static int __init gpio_buttons_init(void)
  10422. +{
  10423. + printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n");
  10424. + return platform_driver_register(&gpio_buttons_driver);
  10425. +}
  10426. +
  10427. +static void __exit gpio_buttons_exit(void)
  10428. +{
  10429. + platform_driver_unregister(&gpio_buttons_driver);
  10430. +}
  10431. +
  10432. +module_init(gpio_buttons_init);
  10433. +module_exit(gpio_buttons_exit);
  10434. +
  10435. +MODULE_LICENSE("GPL");
  10436. +MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
  10437. +MODULE_VERSION(DRV_VERSION);
  10438. +MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs");
  10439. +
  10440. diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c
  10441. --- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100
  10442. +++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-05-27 14:36:51.000000000 +0200
  10443. @@ -0,0 +1,140 @@
  10444. +/*
  10445. + * LED driver for the RouterBOARD 750
  10446. + *
  10447. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  10448. + *
  10449. + * This program is free software; you can redistribute it and/or modify
  10450. + * it under the terms of the GNU General Public License version 2 as
  10451. + * published by the Free Software Foundation.
  10452. + *
  10453. + */
  10454. +#include <linux/kernel.h>
  10455. +#include <linux/init.h>
  10456. +#include <linux/platform_device.h>
  10457. +#include <linux/leds.h>
  10458. +
  10459. +#include <asm/mach-ar71xx/mach-rb750.h>
  10460. +
  10461. +#define DRV_NAME "leds-rb750"
  10462. +
  10463. +struct rb750_led_dev {
  10464. + struct led_classdev cdev;
  10465. + u32 mask;
  10466. + int active_low;
  10467. +};
  10468. +
  10469. +struct rb750_led_drvdata {
  10470. + struct rb750_led_dev *led_devs;
  10471. + int num_leds;
  10472. +};
  10473. +
  10474. +static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev)
  10475. +{
  10476. + return (struct rb750_led_dev *)container_of(led_cdev,
  10477. + struct rb750_led_dev, cdev);
  10478. +}
  10479. +
  10480. +static void rb750_led_brightness_set(struct led_classdev *led_cdev,
  10481. + enum led_brightness value)
  10482. +{
  10483. + struct rb750_led_dev *rbled = to_rbled(led_cdev);
  10484. + int level;
  10485. +
  10486. + level = (value == LED_OFF) ? 0 : 1;
  10487. + level ^= rbled->active_low;
  10488. +
  10489. + if (level)
  10490. + rb750_latch_change(0, rbled->mask);
  10491. + else
  10492. + rb750_latch_change(rbled->mask, 0);
  10493. +}
  10494. +
  10495. +static int __devinit rb750_led_probe(struct platform_device *pdev)
  10496. +{
  10497. + struct rb750_led_platform_data *pdata;
  10498. + struct rb750_led_drvdata *drvdata;
  10499. + int ret = 0;
  10500. + int i;
  10501. +
  10502. + pdata = pdev->dev.platform_data;
  10503. + if (!pdata)
  10504. + return -EINVAL;
  10505. +
  10506. + drvdata = kzalloc(sizeof(struct rb750_led_drvdata) +
  10507. + sizeof(struct rb750_led_dev) * pdata->num_leds,
  10508. + GFP_KERNEL);
  10509. + if (!drvdata)
  10510. + return -ENOMEM;
  10511. +
  10512. + drvdata->num_leds = pdata->num_leds;
  10513. + drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1];
  10514. +
  10515. + for (i = 0; i < drvdata->num_leds; i++) {
  10516. + struct rb750_led_dev *rbled = &drvdata->led_devs[i];
  10517. + struct rb750_led_data *led_data = &pdata->leds[i];
  10518. +
  10519. + rbled->cdev.name = led_data->name;
  10520. + rbled->cdev.default_trigger = led_data->default_trigger;
  10521. + rbled->cdev.brightness_set = rb750_led_brightness_set;
  10522. + rbled->cdev.brightness = LED_OFF;
  10523. +
  10524. + rbled->mask = led_data->mask;
  10525. + rbled->active_low = !!led_data->active_low;
  10526. +
  10527. + ret = led_classdev_register(&pdev->dev, &rbled->cdev);
  10528. + if (ret)
  10529. + goto err;
  10530. + }
  10531. +
  10532. + platform_set_drvdata(pdev, drvdata);
  10533. + return 0;
  10534. +
  10535. + err:
  10536. + for (i = i - 1; i >= 0; i--)
  10537. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10538. +
  10539. + kfree(drvdata);
  10540. + return ret;
  10541. +}
  10542. +
  10543. +static int __devexit rb750_led_remove(struct platform_device *pdev)
  10544. +{
  10545. + struct rb750_led_drvdata *drvdata;
  10546. + int i;
  10547. +
  10548. + drvdata = platform_get_drvdata(pdev);
  10549. + for (i = 0; i < drvdata->num_leds; i++)
  10550. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10551. +
  10552. + kfree(drvdata);
  10553. + return 0;
  10554. +}
  10555. +
  10556. +static struct platform_driver rb750_led_driver = {
  10557. + .probe = rb750_led_probe,
  10558. + .remove = __devexit_p(rb750_led_remove),
  10559. + .driver = {
  10560. + .name = DRV_NAME,
  10561. + .owner = THIS_MODULE,
  10562. + },
  10563. +};
  10564. +
  10565. +MODULE_ALIAS("platform:leds-rb750");
  10566. +
  10567. +static int __init rb750_led_init(void)
  10568. +{
  10569. + return platform_driver_register(&rb750_led_driver);
  10570. +}
  10571. +
  10572. +static void __exit rb750_led_exit(void)
  10573. +{
  10574. + platform_driver_unregister(&rb750_led_driver);
  10575. +}
  10576. +
  10577. +module_init(rb750_led_init);
  10578. +module_exit(rb750_led_exit);
  10579. +
  10580. +MODULE_DESCRIPTION(DRV_NAME);
  10581. +MODULE_DESCRIPTION("LED driver for the RouterBOARD 750");
  10582. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10583. +MODULE_LICENSE("GPL v2");
  10584. diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c
  10585. --- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100
  10586. +++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-05-27 14:36:51.000000000 +0200
  10587. @@ -0,0 +1,75 @@
  10588. +/*
  10589. + * USB LED driver for the NETGEAR WNDR3700
  10590. + *
  10591. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10592. + *
  10593. + * This program is free software; you can redistribute it and/or modify it
  10594. + * under the terms of the GNU General Public License version 2 as published
  10595. + * by the Free Software Foundation.
  10596. + */
  10597. +
  10598. +#include <linux/leds.h>
  10599. +#include <linux/module.h>
  10600. +#include <linux/platform_device.h>
  10601. +
  10602. +#include <asm/mach-ar71xx/ar71xx.h>
  10603. +
  10604. +#define DRIVER_NAME "wndr3700-led-usb"
  10605. +
  10606. +static void wndr3700_usb_led_set(struct led_classdev *cdev,
  10607. + enum led_brightness brightness)
  10608. +{
  10609. + if (brightness)
  10610. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  10611. + else
  10612. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  10613. +}
  10614. +
  10615. +static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev)
  10616. +{
  10617. + return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL;
  10618. +}
  10619. +
  10620. +static struct led_classdev wndr3700_usb_led = {
  10621. + .name = "wndr3700:green:usb",
  10622. + .brightness_set = wndr3700_usb_led_set,
  10623. + .brightness_get = wndr3700_usb_led_get,
  10624. +};
  10625. +
  10626. +static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev)
  10627. +{
  10628. + return led_classdev_register(&pdev->dev, &wndr3700_usb_led);
  10629. +}
  10630. +
  10631. +static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev)
  10632. +{
  10633. + led_classdev_unregister(&wndr3700_usb_led);
  10634. + return 0;
  10635. +}
  10636. +
  10637. +static struct platform_driver wndr3700_usb_led_driver = {
  10638. + .probe = wndr3700_usb_led_probe,
  10639. + .remove = __devexit_p(wndr3700_usb_led_remove),
  10640. + .driver = {
  10641. + .name = DRIVER_NAME,
  10642. + .owner = THIS_MODULE,
  10643. + },
  10644. +};
  10645. +
  10646. +static int __init wndr3700_usb_led_init(void)
  10647. +{
  10648. + return platform_driver_register(&wndr3700_usb_led_driver);
  10649. +}
  10650. +
  10651. +static void __exit wndr3700_usb_led_exit(void)
  10652. +{
  10653. + platform_driver_unregister(&wndr3700_usb_led_driver);
  10654. +}
  10655. +
  10656. +module_init(wndr3700_usb_led_init);
  10657. +module_exit(wndr3700_usb_led_exit);
  10658. +
  10659. +MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700");
  10660. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10661. +MODULE_LICENSE("GPL v2");
  10662. +MODULE_ALIAS("platform:" DRIVER_NAME);
  10663. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig
  10664. --- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200
  10665. +++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-05-27 14:36:51.000000000 +0200
  10666. @@ -260,6 +260,13 @@
  10667. Support for parsing CFE image tag and creating MTD partitions on
  10668. Broadcom BCM63xx boards.
  10669. +config MTD_AR91XX_FLASH
  10670. + tristate "Atheros AR91xx parallel flash support"
  10671. + depends on ATHEROS_AR71XX
  10672. + select MTD_COMPLEX_MAPPINGS
  10673. + help
  10674. + Parallel flash driver for the Atheros AR91xx based boards.
  10675. +
  10676. config MTD_DILNETPC
  10677. tristate "CFI Flash device mapped on DIL/Net PC"
  10678. depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
  10679. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile
  10680. --- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200
  10681. +++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-05-27 14:36:51.000000000 +0200
  10682. @@ -7,6 +7,7 @@
  10683. endif
  10684. # Chip mappings
  10685. +obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o
  10686. obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
  10687. obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
  10688. obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
  10689. diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c
  10690. --- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100
  10691. +++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-05-27 14:36:51.000000000 +0200
  10692. @@ -0,0 +1,310 @@
  10693. +/*
  10694. + * Parallel flash driver for the Atheros AR91xx SoC
  10695. + *
  10696. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10697. + *
  10698. + * This program is free software; you can redistribute it and/or modify
  10699. + * it under the terms of the GNU General Public License version 2 as
  10700. + * published by the Free Software Foundation.
  10701. + *
  10702. + */
  10703. +
  10704. +#include <linux/module.h>
  10705. +#include <linux/types.h>
  10706. +#include <linux/kernel.h>
  10707. +#include <linux/init.h>
  10708. +#include <linux/slab.h>
  10709. +#include <linux/device.h>
  10710. +#include <linux/platform_device.h>
  10711. +#include <linux/mtd/mtd.h>
  10712. +#include <linux/mtd/map.h>
  10713. +#include <linux/mtd/partitions.h>
  10714. +#include <linux/io.h>
  10715. +
  10716. +#include <asm/mach-ar71xx/ar71xx.h>
  10717. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  10718. +
  10719. +#define DRV_NAME "ar91xx-flash"
  10720. +
  10721. +struct ar91xx_flash_info {
  10722. + struct mtd_info *mtd;
  10723. + struct map_info map;
  10724. +#ifdef CONFIG_MTD_PARTITIONS
  10725. + int nr_parts;
  10726. + struct mtd_partition *parts;
  10727. +#endif
  10728. +};
  10729. +
  10730. +static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs)
  10731. +{
  10732. + map_word val;
  10733. +
  10734. + if (map_bankwidth_is_1(map))
  10735. + val.x[0] = __raw_readb(map->virt + (ofs ^ 3));
  10736. + else if (map_bankwidth_is_2(map))
  10737. + val.x[0] = __raw_readw(map->virt + (ofs ^ 2));
  10738. + else
  10739. + val = map_word_ff(map);
  10740. +
  10741. + return val;
  10742. +}
  10743. +
  10744. +static void ar91xx_flash_write(struct map_info *map, map_word d,
  10745. + unsigned long ofs)
  10746. +{
  10747. + if (map_bankwidth_is_1(map))
  10748. + __raw_writeb(d.x[0], map->virt + (ofs ^ 3));
  10749. + else if (map_bankwidth_is_2(map))
  10750. + __raw_writew(d.x[0], map->virt + (ofs ^ 2));
  10751. +
  10752. + mb();
  10753. +}
  10754. +
  10755. +static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs)
  10756. +{
  10757. + map_word ret;
  10758. +
  10759. + ar71xx_flash_acquire();
  10760. + ret = ar91xx_flash_read(map, ofs);
  10761. + ar71xx_flash_release();
  10762. +
  10763. + return ret;
  10764. +}
  10765. +
  10766. +static void ar91xx_flash_write_lock(struct map_info *map, map_word d,
  10767. + unsigned long ofs)
  10768. +{
  10769. + ar71xx_flash_acquire();
  10770. + ar91xx_flash_write(map, d, ofs);
  10771. + ar71xx_flash_release();
  10772. +}
  10773. +
  10774. +static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to,
  10775. + unsigned long from, ssize_t len)
  10776. +{
  10777. + ar71xx_flash_acquire();
  10778. + inline_map_copy_from(map, to, from, len);
  10779. + ar71xx_flash_release();
  10780. +}
  10781. +
  10782. +static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to,
  10783. + const void *from, ssize_t len)
  10784. +{
  10785. + ar71xx_flash_acquire();
  10786. + inline_map_copy_to(map, to, from, len);
  10787. + ar71xx_flash_release();
  10788. +}
  10789. +
  10790. +static int ar91xx_flash_remove(struct platform_device *pdev)
  10791. +{
  10792. + struct ar91xx_flash_platform_data *pdata;
  10793. + struct ar91xx_flash_info *info;
  10794. +
  10795. + info = platform_get_drvdata(pdev);
  10796. + if (info == NULL)
  10797. + return 0;
  10798. +
  10799. + platform_set_drvdata(pdev, NULL);
  10800. +
  10801. + if (info->mtd == NULL)
  10802. + return 0;
  10803. +
  10804. + pdata = pdev->dev.platform_data;
  10805. +#ifdef CONFIG_MTD_PARTITIONS
  10806. + if (info->nr_parts) {
  10807. + del_mtd_partitions(info->mtd);
  10808. + kfree(info->parts);
  10809. + } else if (pdata->nr_parts) {
  10810. + del_mtd_partitions(info->mtd);
  10811. + } else {
  10812. + del_mtd_device(info->mtd);
  10813. + }
  10814. +#else
  10815. + del_mtd_device(info->mtd);
  10816. +#endif
  10817. + map_destroy(info->mtd);
  10818. +
  10819. + return 0;
  10820. +}
  10821. +
  10822. +static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
  10823. +#ifdef CONFIG_MTD_PARTITIONS
  10824. +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  10825. +#endif
  10826. +
  10827. +static int ar91xx_flash_probe(struct platform_device *pdev)
  10828. +{
  10829. + struct ar91xx_flash_platform_data *pdata;
  10830. + struct ar91xx_flash_info *info;
  10831. + struct resource *res;
  10832. + struct resource *region;
  10833. + const char **probe_type;
  10834. + int err = 0;
  10835. +
  10836. + pdata = pdev->dev.platform_data;
  10837. + if (pdata == NULL)
  10838. + return -EINVAL;
  10839. +
  10840. + info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info),
  10841. + GFP_KERNEL);
  10842. + if (info == NULL) {
  10843. + err = -ENOMEM;
  10844. + goto err_out;
  10845. + }
  10846. +
  10847. + platform_set_drvdata(pdev, info);
  10848. +
  10849. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  10850. + if (res == NULL) {
  10851. + err = -ENOENT;
  10852. + goto err_out;
  10853. + }
  10854. +
  10855. + dev_info(&pdev->dev, "%.8llx at %.8llx\n",
  10856. + (unsigned long long)(res->end - res->start + 1),
  10857. + (unsigned long long)res->start);
  10858. +
  10859. + region = devm_request_mem_region(&pdev->dev,
  10860. + res->start, res->end - res->start + 1,
  10861. + dev_name(&pdev->dev));
  10862. + if (region == NULL) {
  10863. + dev_err(&pdev->dev, "could not reserve memory region\n");
  10864. + err = -ENOMEM;
  10865. + goto err_out;
  10866. + }
  10867. +
  10868. + info->map.name = dev_name(&pdev->dev);
  10869. + info->map.phys = res->start;
  10870. + info->map.size = res->end - res->start + 1;
  10871. + info->map.bankwidth = pdata->width;
  10872. +
  10873. + info->map.virt = devm_ioremap(&pdev->dev, info->map.phys,
  10874. + info->map.size);
  10875. + if (info->map.virt == NULL) {
  10876. + dev_err(&pdev->dev, "failed to ioremap flash region\n");
  10877. + err = -EIO;
  10878. + goto err_out;
  10879. + }
  10880. +
  10881. + simple_map_init(&info->map);
  10882. + if (pdata->is_shared) {
  10883. + info->map.read = ar91xx_flash_read_lock;
  10884. + info->map.write = ar91xx_flash_write_lock;
  10885. + info->map.copy_from = ar91xx_flash_copy_from_lock;
  10886. + info->map.copy_to = ar91xx_flash_copy_to_lock;
  10887. + } else {
  10888. + info->map.read = ar91xx_flash_read;
  10889. + info->map.write = ar91xx_flash_write;
  10890. + }
  10891. +
  10892. + probe_type = rom_probe_types;
  10893. + for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
  10894. + info->mtd = do_map_probe(*probe_type, &info->map);
  10895. +
  10896. + if (info->mtd == NULL) {
  10897. + dev_err(&pdev->dev, "map_probe failed\n");
  10898. + err = -ENXIO;
  10899. + goto err_out;
  10900. + }
  10901. +
  10902. + info->mtd->owner = THIS_MODULE;
  10903. +
  10904. +#ifdef CONFIG_MTD_PARTITIONS
  10905. + if (pdata->nr_parts) {
  10906. + dev_info(&pdev->dev, "using static partition mapping\n");
  10907. + add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
  10908. + return 0;
  10909. + }
  10910. +
  10911. + err = parse_mtd_partitions(info->mtd, part_probe_types,
  10912. + &info->parts, 0);
  10913. + if (err > 0) {
  10914. + add_mtd_partitions(info->mtd, info->parts, err);
  10915. + return 0;
  10916. + }
  10917. +#endif
  10918. +
  10919. + add_mtd_device(info->mtd);
  10920. + return 0;
  10921. +
  10922. + err_out:
  10923. + ar91xx_flash_remove(pdev);
  10924. + return err;
  10925. +}
  10926. +
  10927. +#ifdef CONFIG_PM
  10928. +static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state)
  10929. +{
  10930. + struct ar91xx_flash_info *info = platform_get_drvdata(dev);
  10931. + int ret = 0;
  10932. +
  10933. + if (info->mtd->suspend)
  10934. + ret = info->mtd->suspend(info->mtd);
  10935. +
  10936. + if (ret)
  10937. + goto fail;
  10938. +
  10939. + return 0;
  10940. +
  10941. + fail:
  10942. + if (info->mtd->suspend) {
  10943. + BUG_ON(!info->mtd->resume);
  10944. + info->mtd->resume(info->mtd);
  10945. + }
  10946. +
  10947. + return ret;
  10948. +}
  10949. +
  10950. +static int ar91xx_flash_resume(struct platform_device *pdev)
  10951. +{
  10952. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  10953. +
  10954. + if (info->mtd->resume)
  10955. + info->mtd->resume(info->mtd);
  10956. +
  10957. + return 0;
  10958. +}
  10959. +
  10960. +static void ar91xx_flash_shutdown(struct platform_device *pdev)
  10961. +{
  10962. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  10963. +
  10964. + if (info->mtd->suspend && info->mtd->resume)
  10965. + if (info->mtd->suspend(info->mtd) == 0)
  10966. + info->mtd->resume(info->mtd);
  10967. +}
  10968. +#else
  10969. +#define ar91xx_flash_suspend NULL
  10970. +#define ar91xx_flash_resume NULL
  10971. +#define ar91xx_flash_shutdown NULL
  10972. +#endif
  10973. +
  10974. +static struct platform_driver ar91xx_flash_driver = {
  10975. + .probe = ar91xx_flash_probe,
  10976. + .remove = ar91xx_flash_remove,
  10977. + .suspend = ar91xx_flash_suspend,
  10978. + .resume = ar91xx_flash_resume,
  10979. + .shutdown = ar91xx_flash_shutdown,
  10980. + .driver = {
  10981. + .name = DRV_NAME,
  10982. + .owner = THIS_MODULE,
  10983. + },
  10984. +};
  10985. +
  10986. +static int __init ar91xx_flash_init(void)
  10987. +{
  10988. + return platform_driver_register(&ar91xx_flash_driver);
  10989. +}
  10990. +
  10991. +static void __exit ar91xx_flash_exit(void)
  10992. +{
  10993. + platform_driver_unregister(&ar91xx_flash_driver);
  10994. +}
  10995. +
  10996. +module_init(ar91xx_flash_init);
  10997. +module_exit(ar91xx_flash_exit);
  10998. +
  10999. +MODULE_LICENSE("GPL v2");
  11000. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11001. +MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC");
  11002. +MODULE_ALIAS("platform:" DRV_NAME);
  11003. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig
  11004. --- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200
  11005. +++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-05-27 14:36:51.000000000 +0200
  11006. @@ -531,4 +531,8 @@
  11007. Enables support for NAND Flash chips on the ST Microelectronics
  11008. Flexible Static Memory Controller (FSMC)
  11009. +config MTD_NAND_RB4XX
  11010. + tristate "NAND flash driver for RouterBoard 4xx series"
  11011. + depends on MTD_NAND && AR71XX_MACH_RB4XX
  11012. +
  11013. endif # MTD_NAND
  11014. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile
  11015. --- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200
  11016. +++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-05-27 14:36:51.000000000 +0200
  11017. @@ -34,6 +34,7 @@
  11018. obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
  11019. obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
  11020. obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
  11021. +obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
  11022. obj-$(CONFIG_MTD_ALAUDA) += alauda.o
  11023. obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
  11024. obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
  11025. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c
  11026. --- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100
  11027. +++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-05-27 14:36:51.000000000 +0200
  11028. @@ -0,0 +1,513 @@
  11029. +/*
  11030. + * NAND flash driver for the MikroTik RouterBoard 4xx series
  11031. + *
  11032. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  11033. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  11034. + *
  11035. + * This file was based on the driver for Linux 2.6.22 published by
  11036. + * MikroTik for their RouterBoard 4xx series devices.
  11037. + *
  11038. + * This program is free software; you can redistribute it and/or modify it
  11039. + * under the terms of the GNU General Public License version 2 as published
  11040. + * by the Free Software Foundation.
  11041. + */
  11042. +
  11043. +#include <linux/init.h>
  11044. +#include <linux/mtd/nand.h>
  11045. +#include <linux/mtd/mtd.h>
  11046. +#include <linux/mtd/partitions.h>
  11047. +#include <linux/platform_device.h>
  11048. +#include <linux/delay.h>
  11049. +#include <linux/io.h>
  11050. +#include <linux/gpio.h>
  11051. +#include <linux/slab.h>
  11052. +
  11053. +#include <asm/mach-ar71xx/ar71xx.h>
  11054. +
  11055. +#define DRV_NAME "rb4xx-nand"
  11056. +#define DRV_VERSION "0.1.10"
  11057. +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
  11058. +
  11059. +#define USE_FAST_READ 1
  11060. +#define USE_FAST_WRITE 1
  11061. +#undef RB4XX_NAND_DEBUG
  11062. +
  11063. +#ifdef RB4XX_NAND_DEBUG
  11064. +#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg)
  11065. +#else
  11066. +#define DBG(fmt, arg...) do {} while (0)
  11067. +#endif
  11068. +
  11069. +#define RB4XX_NAND_GPIO_RDY 5
  11070. +#define RB4XX_FLASH_HZ 33333334
  11071. +#define RB4XX_NAND_HZ 33333334
  11072. +
  11073. +#define SPI_CTRL_FASTEST 0x40
  11074. +#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */
  11075. +#define SBIT_IOC_BASE SPI_IOC_CS1
  11076. +#define SBIT_IOC_DO_SHIFT 0
  11077. +#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT)
  11078. +#define SBIT_IOC_DO2_SHIFT 18
  11079. +#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT)
  11080. +
  11081. +#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */
  11082. +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */
  11083. +#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */
  11084. +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */
  11085. +
  11086. +#define CFG_BIT_nCE 0x80
  11087. +#define CFG_BIT_CLE 0x40
  11088. +#define CFG_BIT_ALE 0x20
  11089. +#define CFG_BIT_FAN 0x10
  11090. +#define CFG_BIT_nLED4 0x08
  11091. +#define CFG_BIT_nLED3 0x04
  11092. +#define CFG_BIT_nLED2 0x02
  11093. +#define CFG_BIT_nLED1 0x01
  11094. +
  11095. +#define CFG_BIT_nLEDS \
  11096. + (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4)
  11097. +
  11098. +struct rb4xx_nand_info {
  11099. + struct nand_chip chip;
  11100. + struct mtd_info mtd;
  11101. +};
  11102. +
  11103. +/*
  11104. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11105. + * will not be able to find the kernel that we load.
  11106. + */
  11107. +static struct nand_ecclayout rb4xx_nand_ecclayout = {
  11108. + .eccbytes = 6,
  11109. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11110. + .oobavail = 9,
  11111. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11112. +};
  11113. +
  11114. +static struct mtd_partition rb4xx_nand_partitions[] = {
  11115. + {
  11116. + .name = "booter",
  11117. + .offset = 0,
  11118. + .size = (256 * 1024),
  11119. + .mask_flags = MTD_WRITEABLE,
  11120. + },
  11121. + {
  11122. + .name = "kernel",
  11123. + .offset = (256 * 1024),
  11124. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11125. + },
  11126. + {
  11127. + .name = "rootfs",
  11128. + .offset = MTDPART_OFS_NXTBLK,
  11129. + .size = (1024*1024*64) - (1024*256) - (4 * 1024 * 1024)
  11130. + },
  11131. + {
  11132. + .name = "cfgfs",
  11133. + .offset = (1024*1024*64) - (1024*256),
  11134. + .size = (1024*256),
  11135. + },
  11136. +};
  11137. +
  11138. +#if USE_FAST_READ
  11139. +#define SPI_NDATA_BASE 0x00800000
  11140. +static unsigned spi_ctrl_fread = SPI_CTRL_SAFE;
  11141. +static unsigned spi_ctrl_flash = SPI_CTRL_SAFE;
  11142. +extern unsigned mips_hpt_frequency;
  11143. +#endif
  11144. +
  11145. +static inline unsigned rb4xx_spi_rreg(unsigned r)
  11146. +{
  11147. + return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11148. +}
  11149. +
  11150. +static inline void rb4xx_spi_wreg(unsigned r, unsigned v)
  11151. +{
  11152. + __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11153. +}
  11154. +
  11155. +static inline void do_spi_clk(int bit)
  11156. +{
  11157. + unsigned bval = SBIT_IOC_BASE | (bit & 1);
  11158. +
  11159. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11160. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11161. +}
  11162. +
  11163. +static void do_spi_byte(uint8_t byte)
  11164. +{
  11165. + do_spi_clk(byte >> 7);
  11166. + do_spi_clk(byte >> 6);
  11167. + do_spi_clk(byte >> 5);
  11168. + do_spi_clk(byte >> 4);
  11169. + do_spi_clk(byte >> 3);
  11170. + do_spi_clk(byte >> 2);
  11171. + do_spi_clk(byte >> 1);
  11172. + do_spi_clk(byte);
  11173. +
  11174. + DBG("spi_byte sent 0x%02x got 0x%x\n",
  11175. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11176. +}
  11177. +
  11178. +#if USE_FAST_WRITE
  11179. +static inline void do_spi_clk_fast(int bit1, int bit2)
  11180. +{
  11181. + unsigned bval = (SBIT_IOC_BASE |
  11182. + ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) |
  11183. + ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2));
  11184. +
  11185. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11186. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11187. +}
  11188. +
  11189. +static inline void do_spi_byte_fast(uint8_t byte)
  11190. +{
  11191. + do_spi_clk_fast(byte >> 7, byte >> 6);
  11192. + do_spi_clk_fast(byte >> 5, byte >> 4);
  11193. + do_spi_clk_fast(byte >> 3, byte >> 2);
  11194. + do_spi_clk_fast(byte >> 1, byte >> 0);
  11195. +
  11196. + DBG("spi_byte_fast sent 0x%02x got 0x%x\n",
  11197. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11198. +}
  11199. +#else
  11200. +static inline void do_spi_byte_fast(uint8_t byte)
  11201. +{
  11202. + do_spi_byte(byte);
  11203. +}
  11204. +#endif /* USE_FAST_WRITE */
  11205. +
  11206. +static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData,
  11207. + unsigned recvCnt, uint8_t *recvData,
  11208. + const uint8_t *verifyData, int fastWrite)
  11209. +{
  11210. + unsigned i;
  11211. +
  11212. + DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt);
  11213. +
  11214. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11215. + rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST);
  11216. +
  11217. + do_spi_byte(cmd);
  11218. +#if 0
  11219. + if (cmd == CPLD_CMD_READ_FAST) {
  11220. + do_spi_byte(0x80);
  11221. + do_spi_byte(0);
  11222. + do_spi_byte(0);
  11223. + }
  11224. +#endif
  11225. + for (i = 0; i < sendCnt; ++i) {
  11226. + if (fastWrite)
  11227. + do_spi_byte_fast(sendData[i]);
  11228. + else
  11229. + do_spi_byte(sendData[i]);
  11230. + }
  11231. +
  11232. + for (i = 0; i < recvCnt; ++i) {
  11233. + if (fastWrite)
  11234. + do_spi_byte_fast(0);
  11235. + else
  11236. + do_spi_byte(0);
  11237. +
  11238. + if (recvData) {
  11239. + recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff;
  11240. + } else if (verifyData) {
  11241. + if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS)
  11242. + & 0xff))
  11243. + break;
  11244. + }
  11245. + }
  11246. +
  11247. + rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0);
  11248. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash);
  11249. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11250. +
  11251. + return i == recvCnt;
  11252. +}
  11253. +
  11254. +static int got_write = 1;
  11255. +
  11256. +static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt)
  11257. +{
  11258. + do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1);
  11259. + got_write = 1;
  11260. +}
  11261. +
  11262. +static void rb4xx_nand_write_byte(uint8_t byte)
  11263. +{
  11264. + rb4xx_nand_write_data(&byte, 1);
  11265. +}
  11266. +
  11267. +#if USE_FAST_READ
  11268. +static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt)
  11269. +{
  11270. + static unsigned nboffset = 0x100000;
  11271. + unsigned addr;
  11272. +
  11273. + if (got_write) {
  11274. + nboffset = (nboffset + 31) & ~31;
  11275. + if (nboffset >= 0x100000) /* 1MB */
  11276. + nboffset = 0;
  11277. +
  11278. + got_write = 0;
  11279. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11280. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread);
  11281. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11282. + }
  11283. +
  11284. + addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset;
  11285. + DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt);
  11286. +
  11287. + nboffset += cnt;
  11288. + return (uint8_t *)addr;
  11289. +}
  11290. +
  11291. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11292. +{
  11293. + unsigned size32 = cnt & ~31;
  11294. + unsigned remain = cnt & 31;
  11295. +
  11296. + if (size32) {
  11297. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11298. + memcpy(buf, (void *)addr, size32);
  11299. + }
  11300. +
  11301. + if (remain) {
  11302. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11303. + buf + size32, NULL, 0);
  11304. + }
  11305. +}
  11306. +
  11307. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11308. +{
  11309. + unsigned size32 = cnt & ~31;
  11310. + unsigned remain = cnt & 31;
  11311. +
  11312. + if (size32) {
  11313. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11314. + if (memcmp(buf, (void *)addr, size32) != 0)
  11315. + return 0;
  11316. + }
  11317. +
  11318. + if (remain) {
  11319. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11320. + NULL, buf + size32, 0);
  11321. + }
  11322. + return 1;
  11323. +}
  11324. +#else /* USE_FAST_READ */
  11325. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11326. +{
  11327. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0);
  11328. +}
  11329. +
  11330. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11331. +{
  11332. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0);
  11333. +}
  11334. +#endif /* USE_FAST_READ */
  11335. +
  11336. +static void rb4xx_nand_write_cfg(uint8_t byte)
  11337. +{
  11338. + do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0);
  11339. + got_write = 1;
  11340. +}
  11341. +
  11342. +static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
  11343. +{
  11344. + return gpio_get_value(RB4XX_NAND_GPIO_RDY);
  11345. +}
  11346. +
  11347. +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11348. + unsigned int ctrl)
  11349. +{
  11350. + if (ctrl & NAND_CTRL_CHANGE) {
  11351. + uint8_t cfg = CFG_BIT_nLEDS;
  11352. +
  11353. + cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0;
  11354. + cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0;
  11355. + cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE;
  11356. +
  11357. + rb4xx_nand_write_cfg(cfg);
  11358. + }
  11359. +
  11360. + if (cmd != NAND_CMD_NONE)
  11361. + rb4xx_nand_write_byte(cmd);
  11362. +}
  11363. +
  11364. +static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd)
  11365. +{
  11366. + uint8_t byte = 0;
  11367. +
  11368. + rb4xx_nand_read_data(&byte, 1);
  11369. + return byte;
  11370. +}
  11371. +
  11372. +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
  11373. + int len)
  11374. +{
  11375. + rb4xx_nand_write_data(buf, len);
  11376. +}
  11377. +
  11378. +static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf,
  11379. + int len)
  11380. +{
  11381. + rb4xx_nand_read_data(buf, len);
  11382. +}
  11383. +
  11384. +static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
  11385. + int len)
  11386. +{
  11387. + if (!rb4xx_nand_verify_data(buf, len))
  11388. + return -EFAULT;
  11389. +
  11390. + return 0;
  11391. +}
  11392. +
  11393. +static unsigned get_spi_ctrl(unsigned hz_max, const char *name)
  11394. +{
  11395. + unsigned div;
  11396. +
  11397. + div = (ar71xx_ahb_freq - 1) / (2 * hz_max);
  11398. + /*
  11399. + * CPU has a bug at (div == 0) - first bit read is random
  11400. + */
  11401. + if (div == 0)
  11402. + ++div;
  11403. +
  11404. + if (name) {
  11405. + unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000;
  11406. + unsigned div_real = 2 * (div + 1);
  11407. + printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n",
  11408. + name,
  11409. + ahb_khz / div_real,
  11410. + ahb_khz, div_real);
  11411. + }
  11412. +
  11413. + return SPI_CTRL_FASTEST + div;
  11414. +}
  11415. +
  11416. +static int __init rb4xx_nand_probe(struct platform_device *pdev)
  11417. +{
  11418. + struct rb4xx_nand_info *info;
  11419. + int ret;
  11420. +
  11421. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  11422. +
  11423. + ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY");
  11424. + if (ret) {
  11425. + printk(KERN_ERR "rb4xx-nand: gpio request failed\n");
  11426. + return ret;
  11427. + }
  11428. +
  11429. + ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY);
  11430. + if (ret) {
  11431. + printk(KERN_ERR "rb4xx-nand: unable to set input mode "
  11432. + "on gpio%d\n", RB4XX_NAND_GPIO_RDY);
  11433. + goto err_free_gpio;
  11434. + }
  11435. +
  11436. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  11437. + if (!info) {
  11438. + printk(KERN_ERR "rb4xx-nand: no memory for private data\n");
  11439. + ret = -ENOMEM;
  11440. + goto err_free_gpio;
  11441. + }
  11442. +
  11443. +#if USE_FAST_READ
  11444. + spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND");
  11445. +#endif
  11446. + spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH");
  11447. +
  11448. + rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE);
  11449. +
  11450. + info->chip.priv = &info;
  11451. + info->mtd.priv = &info->chip;
  11452. + info->mtd.owner = THIS_MODULE;
  11453. +
  11454. + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
  11455. + info->chip.dev_ready = rb4xx_nand_dev_ready;
  11456. + info->chip.read_byte = rb4xx_nand_read_byte;
  11457. + info->chip.write_buf = rb4xx_nand_write_buf;
  11458. + info->chip.read_buf = rb4xx_nand_read_buf;
  11459. + info->chip.verify_buf = rb4xx_nand_verify_buf;
  11460. +
  11461. + info->chip.chip_delay = 25;
  11462. + info->chip.ecc.mode = NAND_ECC_SOFT;
  11463. + info->chip.options |= NAND_NO_AUTOINCR;
  11464. +
  11465. + platform_set_drvdata(pdev, info);
  11466. +
  11467. + ret = nand_scan_ident(&info->mtd, 1, NULL);
  11468. + if (ret) {
  11469. + ret = -ENXIO;
  11470. + goto err_free_info;
  11471. + }
  11472. +
  11473. + if (info->mtd.writesize == 512)
  11474. + info->chip.ecc.layout = &rb4xx_nand_ecclayout;
  11475. +
  11476. + ret = nand_scan_tail(&info->mtd);
  11477. + if (ret) {
  11478. + return -ENXIO;
  11479. + goto err_set_drvdata;
  11480. + }
  11481. +
  11482. +#ifdef CONFIG_MTD_PARTITIONS
  11483. + ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions,
  11484. + ARRAY_SIZE(rb4xx_nand_partitions));
  11485. +#else
  11486. + ret = add_mtd_device(&info->mtd);
  11487. +#endif
  11488. + if (ret)
  11489. + goto err_release_nand;
  11490. +
  11491. + return 0;
  11492. +
  11493. +err_release_nand:
  11494. + nand_release(&info->mtd);
  11495. +err_set_drvdata:
  11496. + platform_set_drvdata(pdev, NULL);
  11497. +err_free_info:
  11498. + kfree(info);
  11499. +err_free_gpio:
  11500. + gpio_free(RB4XX_NAND_GPIO_RDY);
  11501. + return ret;
  11502. +}
  11503. +
  11504. +static int __devexit rb4xx_nand_remove(struct platform_device *pdev)
  11505. +{
  11506. + struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
  11507. +
  11508. + nand_release(&info->mtd);
  11509. + platform_set_drvdata(pdev, NULL);
  11510. + kfree(info);
  11511. +
  11512. + return 0;
  11513. +}
  11514. +
  11515. +static struct platform_driver rb4xx_nand_driver = {
  11516. + .probe = rb4xx_nand_probe,
  11517. + .remove = __devexit_p(rb4xx_nand_remove),
  11518. + .driver = {
  11519. + .name = DRV_NAME,
  11520. + .owner = THIS_MODULE,
  11521. + },
  11522. +};
  11523. +
  11524. +static int __init rb4xx_nand_init(void)
  11525. +{
  11526. + return platform_driver_register(&rb4xx_nand_driver);
  11527. +}
  11528. +
  11529. +static void __exit rb4xx_nand_exit(void)
  11530. +{
  11531. + platform_driver_unregister(&rb4xx_nand_driver);
  11532. +}
  11533. +
  11534. +module_init(rb4xx_nand_init);
  11535. +module_exit(rb4xx_nand_exit);
  11536. +
  11537. +MODULE_DESCRIPTION(DRV_DESC);
  11538. +MODULE_VERSION(DRV_VERSION);
  11539. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11540. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  11541. +MODULE_LICENSE("GPL v2");
  11542. diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c
  11543. --- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100
  11544. +++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-05-27 14:36:51.000000000 +0200
  11545. @@ -0,0 +1,360 @@
  11546. +/*
  11547. + * NAND flash driver for the MikroTik RouterBOARD 750
  11548. + *
  11549. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  11550. + *
  11551. + * This program is free software; you can redistribute it and/or modify it
  11552. + * under the terms of the GNU General Public License version 2 as published
  11553. + * by the Free Software Foundation.
  11554. + */
  11555. +
  11556. +#include <linux/init.h>
  11557. +#include <linux/mtd/nand.h>
  11558. +#include <linux/mtd/mtd.h>
  11559. +#include <linux/mtd/partitions.h>
  11560. +#include <linux/platform_device.h>
  11561. +#include <linux/io.h>
  11562. +
  11563. +#include <asm/mach-ar71xx/ar71xx.h>
  11564. +#include <asm/mach-ar71xx/mach-rb750.h>
  11565. +
  11566. +#define DRV_NAME "rb750-nand"
  11567. +#define DRV_VERSION "0.1.0"
  11568. +#define DRV_DESC "NAND flash driver for the RouterBOARD 750"
  11569. +
  11570. +#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0)
  11571. +#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE)
  11572. +#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE)
  11573. +#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE)
  11574. +#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE)
  11575. +#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY)
  11576. +#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE)
  11577. +
  11578. +#define RB750_NAND_DATA_SHIFT 1
  11579. +#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT)
  11580. +#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY)
  11581. +#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \
  11582. + RB750_NAND_NRE | RB750_NAND_NWE | \
  11583. + RB750_NAND_NCE)
  11584. +
  11585. +struct rb750_nand_info {
  11586. + struct nand_chip chip;
  11587. + struct mtd_info mtd;
  11588. +};
  11589. +
  11590. +/*
  11591. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11592. + * will not be able to find the kernel that we load.
  11593. + */
  11594. +static struct nand_ecclayout rb750_nand_ecclayout = {
  11595. + .eccbytes = 6,
  11596. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11597. + .oobavail = 9,
  11598. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11599. +};
  11600. +
  11601. +static struct mtd_partition rb750_nand_partitions[] = {
  11602. + {
  11603. + .name = "booter",
  11604. + .offset = 0,
  11605. + .size = (256 * 1024),
  11606. + .mask_flags = MTD_WRITEABLE,
  11607. + }, {
  11608. + .name = "kernel",
  11609. + .offset = (256 * 1024),
  11610. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11611. + }, {
  11612. + .name = "rootfs",
  11613. + .offset = MTDPART_OFS_NXTBLK,
  11614. + .size = MTDPART_SIZ_FULL,
  11615. + },
  11616. +};
  11617. +
  11618. +static void rb750_nand_write(const u8 *buf, unsigned len)
  11619. +{
  11620. + void __iomem *base = ar71xx_gpio_base;
  11621. + u32 out;
  11622. + unsigned i;
  11623. +
  11624. + /* set data lines to output mode */
  11625. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS,
  11626. + base + GPIO_REG_OE);
  11627. +
  11628. + out = __raw_readl(base + GPIO_REG_OUT);
  11629. + out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE);
  11630. + for (i = 0; i != len; i++) {
  11631. + u32 data;
  11632. +
  11633. + data = buf[i];
  11634. + data <<= RB750_NAND_DATA_SHIFT;
  11635. + data |= out;
  11636. + __raw_writel(data, base + GPIO_REG_OUT);
  11637. +
  11638. + __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT);
  11639. + /* flush write */
  11640. + __raw_readl(base + GPIO_REG_OUT);
  11641. + }
  11642. +
  11643. + /* set data lines to input mode */
  11644. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS,
  11645. + base + GPIO_REG_OE);
  11646. + /* flush write */
  11647. + __raw_readl(base + GPIO_REG_OE);
  11648. +}
  11649. +
  11650. +static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
  11651. + const u8 *verify_buf)
  11652. +{
  11653. + void __iomem *base = ar71xx_gpio_base;
  11654. + unsigned i;
  11655. +
  11656. + for (i = 0; i < len; i++) {
  11657. + u8 data;
  11658. +
  11659. + /* activate RE line */
  11660. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR);
  11661. + /* flush write */
  11662. + __raw_readl(base + GPIO_REG_CLEAR);
  11663. +
  11664. + /* read input lines */
  11665. + data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT;
  11666. +
  11667. + /* deactivate RE line */
  11668. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET);
  11669. +
  11670. + if (read_buf)
  11671. + read_buf[i] = data;
  11672. + else if (verify_buf && verify_buf[i] != data)
  11673. + return -EFAULT;
  11674. + }
  11675. +
  11676. + return 0;
  11677. +}
  11678. +
  11679. +static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
  11680. +{
  11681. + void __iomem *base = ar71xx_gpio_base;
  11682. + u32 func;
  11683. +
  11684. + func = __raw_readl(base + GPIO_REG_FUNC);
  11685. + if (chip >= 0) {
  11686. + /* disable latch */
  11687. + rb750_latch_change(RB750_LVC573_LE, 0);
  11688. +
  11689. + /* disable alternate functions */
  11690. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
  11691. + AR724X_GPIO_FUNC_SPI_EN);
  11692. +
  11693. + /* set input mode for data lines */
  11694. + __raw_writel(__raw_readl(base + GPIO_REG_OE) &
  11695. + ~RB750_NAND_INPUT_BITS,
  11696. + base + GPIO_REG_OE);
  11697. +
  11698. + /* deactivate RE and WE lines */
  11699. + __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE,
  11700. + base + GPIO_REG_SET);
  11701. + /* flush write */
  11702. + (void) __raw_readl(base + GPIO_REG_SET);
  11703. +
  11704. + /* activate CE line */
  11705. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR);
  11706. + } else {
  11707. + /* deactivate CE line */
  11708. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET);
  11709. + /* flush write */
  11710. + (void) __raw_readl(base + GPIO_REG_SET);
  11711. +
  11712. + __raw_writel(__raw_readl(base + GPIO_REG_OE) |
  11713. + RB750_NAND_IO0 | RB750_NAND_RDY,
  11714. + base + GPIO_REG_OE);
  11715. +
  11716. + /* restore alternate functions */
  11717. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
  11718. + AR724X_GPIO_FUNC_JTAG_DISABLE);
  11719. +
  11720. + /* enable latch */
  11721. + rb750_latch_change(0, RB750_LVC573_LE);
  11722. + }
  11723. +}
  11724. +
  11725. +static int rb750_nand_dev_ready(struct mtd_info *mtd)
  11726. +{
  11727. + void __iomem *base = ar71xx_gpio_base;
  11728. +
  11729. + return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY);
  11730. +}
  11731. +
  11732. +static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11733. + unsigned int ctrl)
  11734. +{
  11735. + if (ctrl & NAND_CTRL_CHANGE) {
  11736. + void __iomem *base = ar71xx_gpio_base;
  11737. + u32 t;
  11738. +
  11739. + t = __raw_readl(base + GPIO_REG_OUT);
  11740. +
  11741. + t &= ~(RB750_NAND_CLE | RB750_NAND_ALE);
  11742. + t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0;
  11743. + t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0;
  11744. +
  11745. + __raw_writel(t, base + GPIO_REG_OUT);
  11746. + /* flush write */
  11747. + __raw_readl(base + GPIO_REG_OUT);
  11748. + }
  11749. +
  11750. + if (cmd != NAND_CMD_NONE) {
  11751. + u8 t = cmd;
  11752. + rb750_nand_write(&t, 1);
  11753. + }
  11754. +}
  11755. +
  11756. +static u8 rb750_nand_read_byte(struct mtd_info *mtd)
  11757. +{
  11758. + u8 data = 0;
  11759. + rb750_nand_read_verify(&data, 1, NULL);
  11760. + return data;
  11761. +}
  11762. +
  11763. +static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
  11764. +{
  11765. + rb750_nand_read_verify(buf, len, NULL);
  11766. +}
  11767. +
  11768. +static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11769. +{
  11770. + rb750_nand_write(buf, len);
  11771. +}
  11772. +
  11773. +static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11774. +{
  11775. + return rb750_nand_read_verify(NULL, len, buf);
  11776. +}
  11777. +
  11778. +static void __init rb750_nand_gpio_init(void)
  11779. +{
  11780. + void __iomem *base = ar71xx_gpio_base;
  11781. + u32 out;
  11782. +
  11783. + out = __raw_readl(base + GPIO_REG_OUT);
  11784. +
  11785. + /* setup output levels */
  11786. + __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE,
  11787. + base + GPIO_REG_SET);
  11788. +
  11789. + __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE,
  11790. + base + GPIO_REG_CLEAR);
  11791. +
  11792. + /* setup input lines */
  11793. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS),
  11794. + base + GPIO_REG_OE);
  11795. +
  11796. + /* setup output lines */
  11797. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS,
  11798. + base + GPIO_REG_OE);
  11799. +
  11800. + rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
  11801. +}
  11802. +
  11803. +static int __init rb750_nand_probe(struct platform_device *pdev)
  11804. +{
  11805. + struct rb750_nand_info *info;
  11806. + int ret;
  11807. +
  11808. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  11809. +
  11810. + rb750_nand_gpio_init();
  11811. +
  11812. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  11813. + if (!info)
  11814. + return -ENOMEM;
  11815. +
  11816. + info->chip.priv = &info;
  11817. + info->mtd.priv = &info->chip;
  11818. + info->mtd.owner = THIS_MODULE;
  11819. +
  11820. + info->chip.select_chip = rb750_nand_select_chip;
  11821. + info->chip.cmd_ctrl = rb750_nand_cmd_ctrl;
  11822. + info->chip.dev_ready = rb750_nand_dev_ready;
  11823. + info->chip.read_byte = rb750_nand_read_byte;
  11824. + info->chip.write_buf = rb750_nand_write_buf;
  11825. + info->chip.read_buf = rb750_nand_read_buf;
  11826. + info->chip.verify_buf = rb750_nand_verify_buf;
  11827. +
  11828. + info->chip.chip_delay = 25;
  11829. + info->chip.ecc.mode = NAND_ECC_SOFT;
  11830. + info->chip.options |= NAND_NO_AUTOINCR;
  11831. +
  11832. + platform_set_drvdata(pdev, info);
  11833. +
  11834. + ret = nand_scan_ident(&info->mtd, 1);
  11835. + if (ret) {
  11836. + ret = -ENXIO;
  11837. + goto err_free_info;
  11838. + }
  11839. +
  11840. + if (info->mtd.writesize == 512)
  11841. + info->chip.ecc.layout = &rb750_nand_ecclayout;
  11842. +
  11843. + ret = nand_scan_tail(&info->mtd);
  11844. + if (ret) {
  11845. + return -ENXIO;
  11846. + goto err_set_drvdata;
  11847. + }
  11848. +
  11849. +#ifdef CONFIG_MTD_PARTITIONS
  11850. + ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions,
  11851. + ARRAY_SIZE(rb750_nand_partitions));
  11852. +#else
  11853. + ret = add_mtd_device(&info->mtd);
  11854. +#endif
  11855. + if (ret)
  11856. + goto err_release_nand;
  11857. +
  11858. + return 0;
  11859. +
  11860. + err_release_nand:
  11861. + nand_release(&info->mtd);
  11862. + err_set_drvdata:
  11863. + platform_set_drvdata(pdev, NULL);
  11864. + err_free_info:
  11865. + kfree(info);
  11866. + return ret;
  11867. +}
  11868. +
  11869. +static int __devexit rb750_nand_remove(struct platform_device *pdev)
  11870. +{
  11871. + struct rb750_nand_info *info = platform_get_drvdata(pdev);
  11872. +
  11873. + nand_release(&info->mtd);
  11874. + platform_set_drvdata(pdev, NULL);
  11875. + kfree(info);
  11876. +
  11877. + return 0;
  11878. +}
  11879. +
  11880. +static struct platform_driver rb750_nand_driver = {
  11881. + .probe = rb750_nand_probe,
  11882. + .remove = __devexit_p(rb750_nand_remove),
  11883. + .driver = {
  11884. + .name = DRV_NAME,
  11885. + .owner = THIS_MODULE,
  11886. + },
  11887. +};
  11888. +
  11889. +static int __init rb750_nand_init(void)
  11890. +{
  11891. + return platform_driver_register(&rb750_nand_driver);
  11892. +}
  11893. +
  11894. +static void __exit rb750_nand_exit(void)
  11895. +{
  11896. + platform_driver_unregister(&rb750_nand_driver);
  11897. +}
  11898. +
  11899. +module_init(rb750_nand_init);
  11900. +module_exit(rb750_nand_exit);
  11901. +
  11902. +MODULE_DESCRIPTION(DRV_DESC);
  11903. +MODULE_VERSION(DRV_VERSION);
  11904. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11905. +MODULE_LICENSE("GPL v2");
  11906. diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c
  11907. --- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100
  11908. +++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-05-27 14:36:51.000000000 +0200
  11909. @@ -0,0 +1,181 @@
  11910. +/*
  11911. + * Copyright (C) 2009 Christian Daniel <cd@maintech.de>
  11912. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  11913. + *
  11914. + * This program is free software; you can redistribute it and/or modify
  11915. + * it under the terms of the GNU General Public License as published by
  11916. + * the Free Software Foundation; either version 2 of the License, or
  11917. + * (at your option) any later version.
  11918. + *
  11919. + * This program is distributed in the hope that it will be useful,
  11920. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11921. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11922. + * GNU General Public License for more details.
  11923. + *
  11924. + * You should have received a copy of the GNU General Public License
  11925. + * along with this program; if not, write to the Free Software
  11926. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11927. + *
  11928. + * TRX flash partition table.
  11929. + * Based on ar7 map by Felix Fietkau <nbd@openwrt.org>
  11930. + *
  11931. + */
  11932. +
  11933. +#include <linux/kernel.h>
  11934. +#include <linux/slab.h>
  11935. +#include <linux/vmalloc.h>
  11936. +
  11937. +#include <linux/mtd/mtd.h>
  11938. +#include <linux/mtd/partitions.h>
  11939. +
  11940. +struct cybertan_header {
  11941. + char magic[4];
  11942. + u8 res1[4];
  11943. + char fw_date[3];
  11944. + char fw_ver[3];
  11945. + char id[4];
  11946. + char hw_ver;
  11947. + char unused;
  11948. + u8 flags[2];
  11949. + u8 res2[10];
  11950. +};
  11951. +
  11952. +#define TRX_PARTS 6
  11953. +#define TRX_MAGIC 0x30524448
  11954. +#define TRX_MAX_OFFSET 3
  11955. +
  11956. +struct trx_header {
  11957. + uint32_t magic; /* "HDR0" */
  11958. + uint32_t len; /* Length of file including header */
  11959. + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
  11960. + uint32_t flag_version; /* 0:15 flags, 16:31 version */
  11961. + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
  11962. +};
  11963. +
  11964. +#define IH_MAGIC 0x27051956 /* Image Magic Number */
  11965. +#define IH_NMLEN 32 /* Image Name Length */
  11966. +
  11967. +struct uimage_header {
  11968. + uint32_t ih_magic; /* Image Header Magic Number */
  11969. + uint32_t ih_hcrc; /* Image Header CRC Checksum */
  11970. + uint32_t ih_time; /* Image Creation Timestamp */
  11971. + uint32_t ih_size; /* Image Data Size */
  11972. + uint32_t ih_load; /* Data» Load Address */
  11973. + uint32_t ih_ep; /* Entry Point Address */
  11974. + uint32_t ih_dcrc; /* Image Data CRC Checksum */
  11975. + uint8_t ih_os; /* Operating System */
  11976. + uint8_t ih_arch; /* CPU architecture */
  11977. + uint8_t ih_type; /* Image Type */
  11978. + uint8_t ih_comp; /* Compression Type */
  11979. + uint8_t ih_name[IH_NMLEN]; /* Image Name */
  11980. +};
  11981. +
  11982. +struct wrt160nl_header {
  11983. + struct cybertan_header cybertan;
  11984. + struct trx_header trx;
  11985. + struct uimage_header uimage;
  11986. +} __attribute__ ((packed));
  11987. +
  11988. +static struct mtd_partition trx_parts[TRX_PARTS];
  11989. +
  11990. +static int wrt160nl_parse_partitions(struct mtd_info *master,
  11991. + struct mtd_partition **pparts,
  11992. + unsigned long origin)
  11993. +{
  11994. + struct wrt160nl_header *header;
  11995. + struct trx_header *theader;
  11996. + struct uimage_header *uheader;
  11997. + size_t retlen;
  11998. + unsigned int kernel_len;
  11999. + int ret;
  12000. +
  12001. + header = vmalloc(sizeof(*header));
  12002. + if (!header) {
  12003. + return -ENOMEM;
  12004. + goto out;
  12005. + }
  12006. +
  12007. + ret = master->read(master, 4 * master->erasesize, sizeof(*header),
  12008. + &retlen, (void *) header);
  12009. + if (ret)
  12010. + goto free_hdr;
  12011. +
  12012. + if (retlen != sizeof(*header)) {
  12013. + ret = -EIO;
  12014. + goto free_hdr;
  12015. + }
  12016. +
  12017. + if (strncmp(header->cybertan.magic, "NL16", 4) != 0) {
  12018. + printk(KERN_NOTICE "%s: no WRT160NL signature found\n",
  12019. + master->name);
  12020. + goto free_hdr;
  12021. + }
  12022. +
  12023. + theader = &header->trx;
  12024. + if (le32_to_cpu(theader->magic) != TRX_MAGIC) {
  12025. + printk(KERN_NOTICE "%s: no TRX header found\n", master->name);
  12026. + goto free_hdr;
  12027. + }
  12028. +
  12029. + uheader = &header->uimage;
  12030. + if (uheader->ih_magic != IH_MAGIC) {
  12031. + printk(KERN_NOTICE "%s: no uImage found\n", master->name);
  12032. + goto free_hdr;
  12033. + }
  12034. +
  12035. + kernel_len = le32_to_cpu(theader->offsets[1]) + sizeof(struct cybertan_header);
  12036. +
  12037. + trx_parts[0].name = "u-boot";
  12038. + trx_parts[0].offset = 0;
  12039. + trx_parts[0].size = 4 * master->erasesize;
  12040. + trx_parts[0].mask_flags = MTD_WRITEABLE;
  12041. +
  12042. + trx_parts[1].name = "kernel";
  12043. + trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size;
  12044. + trx_parts[1].size = kernel_len;
  12045. + trx_parts[1].mask_flags = 0;
  12046. +
  12047. + trx_parts[2].name = "rootfs";
  12048. + trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size;
  12049. + trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size;
  12050. + trx_parts[2].mask_flags = 0;
  12051. +
  12052. + trx_parts[3].name = "nvram";
  12053. + trx_parts[3].offset = master->size - 2 * master->erasesize;
  12054. + trx_parts[3].size = master->erasesize;
  12055. + trx_parts[3].mask_flags = MTD_WRITEABLE;
  12056. +
  12057. + trx_parts[4].name = "art";
  12058. + trx_parts[4].offset = master->size - master->erasesize;
  12059. + trx_parts[4].size = master->erasesize;
  12060. + trx_parts[4].mask_flags = MTD_WRITEABLE;
  12061. +
  12062. + trx_parts[5].name = "firmware";
  12063. + trx_parts[5].offset = 4 * master->erasesize;
  12064. + trx_parts[5].size = master->size - 6 * master->erasesize;
  12065. + trx_parts[5].mask_flags = 0;
  12066. +
  12067. + *pparts = trx_parts;
  12068. + ret = TRX_PARTS;
  12069. +
  12070. + free_hdr:
  12071. + vfree(header);
  12072. + out:
  12073. + return ret;
  12074. +}
  12075. +
  12076. +static struct mtd_part_parser wrt160nl_parser = {
  12077. + .owner = THIS_MODULE,
  12078. + .parse_fn = wrt160nl_parse_partitions,
  12079. + .name = "wrt160nl",
  12080. +};
  12081. +
  12082. +static int __init wrt160nl_parser_init(void)
  12083. +{
  12084. + return register_mtd_parser(&wrt160nl_parser);
  12085. +}
  12086. +
  12087. +module_init(wrt160nl_parser_init);
  12088. +
  12089. +MODULE_LICENSE("GPL");
  12090. +MODULE_AUTHOR("Christian Daniel <cd@maintech.de>");
  12091. diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig
  12092. --- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200
  12093. +++ linux-2.6.39/drivers/net/Kconfig 2011-05-27 14:36:51.000000000 +0200
  12094. @@ -2071,6 +2071,8 @@
  12095. The safe and default value for this is N.
  12096. +source drivers/net/ag71xx/Kconfig
  12097. +
  12098. config DL2K
  12099. tristate "DL2000/TC902x-based Gigabit Ethernet support"
  12100. depends on PCI
  12101. diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile
  12102. --- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200
  12103. +++ linux-2.6.39/drivers/net/Makefile 2011-05-27 14:36:51.000000000 +0200
  12104. @@ -112,6 +112,7 @@
  12105. # end link order section
  12106. #
  12107. +obj-$(CONFIG_AG71XX) += ag71xx/
  12108. obj-$(CONFIG_SUNDANCE) += sundance.o
  12109. obj-$(CONFIG_HAMACHI) += hamachi.o
  12110. obj-$(CONFIG_NET) += Space.o loopback.o
  12111. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig
  12112. --- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  12113. +++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-05-27 14:36:51.000000000 +0200
  12114. @@ -0,0 +1,33 @@
  12115. +config AG71XX
  12116. + tristate "Atheros AR71xx built-in ethernet mac support"
  12117. + depends on ATHEROS_AR71XX
  12118. + select PHYLIB
  12119. + help
  12120. + If you wish to compile a kernel for AR71xx/91xx and enable
  12121. + ethernet support, then you should always answer Y to this.
  12122. +
  12123. +if AG71XX
  12124. +
  12125. +config AG71XX_DEBUG
  12126. + bool "Atheros AR71xx built-in ethernet driver debugging"
  12127. + default n
  12128. + help
  12129. + Atheros AR71xx built-in ethernet driver debugging messages.
  12130. +
  12131. +config AG71XX_DEBUG_FS
  12132. + bool "Atheros AR71xx built-in ethernet driver debugfs support"
  12133. + depends on DEBUG_FS
  12134. + default n
  12135. + help
  12136. + Say Y, if you need access to various statistics provided by
  12137. + the ag71xx driver.
  12138. +
  12139. +config AG71XX_AR8216_SUPPORT
  12140. + bool "special support for the Atheros AR8216 switch"
  12141. + default n
  12142. + default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU
  12143. + help
  12144. + Say 'y' here if you want to enable special support for the
  12145. + Atheros AR8216 switch found on some boards.
  12146. +
  12147. +endif
  12148. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile
  12149. --- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  12150. +++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-05-27 14:36:51.000000000 +0200
  12151. @@ -0,0 +1,14 @@
  12152. +#
  12153. +# Makefile for the Atheros AR71xx built-in ethernet macs
  12154. +#
  12155. +
  12156. +ag71xx-y += ag71xx_main.o
  12157. +ag71xx-y += ag71xx_ethtool.o
  12158. +ag71xx-y += ag71xx_phy.o
  12159. +ag71xx-y += ag71xx_mdio.o
  12160. +
  12161. +ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o
  12162. +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o
  12163. +
  12164. +obj-$(CONFIG_AG71XX) += ag71xx.o
  12165. +
  12166. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h
  12167. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100
  12168. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-05-27 14:36:51.000000000 +0200
  12169. @@ -0,0 +1,500 @@
  12170. +/*
  12171. + * Atheros AR71xx built-in ethernet mac driver
  12172. + *
  12173. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12174. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12175. + *
  12176. + * Based on Atheros' AG7100 driver
  12177. + *
  12178. + * This program is free software; you can redistribute it and/or modify it
  12179. + * under the terms of the GNU General Public License version 2 as published
  12180. + * by the Free Software Foundation.
  12181. + */
  12182. +
  12183. +#ifndef __AG71XX_H
  12184. +#define __AG71XX_H
  12185. +
  12186. +#include <linux/kernel.h>
  12187. +#include <linux/version.h>
  12188. +#include <linux/module.h>
  12189. +#include <linux/init.h>
  12190. +#include <linux/types.h>
  12191. +#include <linux/random.h>
  12192. +#include <linux/spinlock.h>
  12193. +#include <linux/interrupt.h>
  12194. +#include <linux/platform_device.h>
  12195. +#include <linux/ethtool.h>
  12196. +#include <linux/etherdevice.h>
  12197. +#include <linux/phy.h>
  12198. +#include <linux/skbuff.h>
  12199. +#include <linux/dma-mapping.h>
  12200. +#include <linux/workqueue.h>
  12201. +
  12202. +#include <linux/bitops.h>
  12203. +
  12204. +#include <asm/mach-ar71xx/ar71xx.h>
  12205. +#include <asm/mach-ar71xx/platform.h>
  12206. +
  12207. +#define ETH_FCS_LEN 4
  12208. +
  12209. +#define AG71XX_DRV_NAME "ag71xx"
  12210. +#define AG71XX_DRV_VERSION "0.5.35"
  12211. +
  12212. +#define AG71XX_NAPI_WEIGHT 64
  12213. +#define AG71XX_OOM_REFILL (1 + HZ/10)
  12214. +
  12215. +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
  12216. +#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
  12217. +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
  12218. +
  12219. +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
  12220. +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
  12221. +
  12222. +#define AG71XX_TX_FIFO_LEN 2048
  12223. +#define AG71XX_TX_MTU_LEN 1536
  12224. +#define AG71XX_RX_PKT_RESERVE 64
  12225. +#define AG71XX_RX_PKT_SIZE \
  12226. + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
  12227. +
  12228. +#define AG71XX_TX_RING_SIZE 64
  12229. +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
  12230. +#define AG71XX_TX_THRES_WAKEUP \
  12231. + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
  12232. +
  12233. +#define AG71XX_RX_RING_SIZE 128
  12234. +
  12235. +#ifdef CONFIG_AG71XX_DEBUG
  12236. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  12237. +#else
  12238. +#define DBG(fmt, args...) do {} while (0)
  12239. +#endif
  12240. +
  12241. +#define ag71xx_assert(_cond) \
  12242. +do { \
  12243. + if (_cond) \
  12244. + break; \
  12245. + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \
  12246. + BUG(); \
  12247. +} while (0)
  12248. +
  12249. +struct ag71xx_desc {
  12250. + u32 data;
  12251. + u32 ctrl;
  12252. +#define DESC_EMPTY BIT(31)
  12253. +#define DESC_MORE BIT(24)
  12254. +#define DESC_PKTLEN_M 0xfff
  12255. + u32 next;
  12256. + u32 pad;
  12257. +} __attribute__((aligned(4)));
  12258. +
  12259. +struct ag71xx_buf {
  12260. + struct sk_buff *skb;
  12261. + struct ag71xx_desc *desc;
  12262. + dma_addr_t dma_addr;
  12263. + u32 pad;
  12264. +};
  12265. +
  12266. +struct ag71xx_ring {
  12267. + struct ag71xx_buf *buf;
  12268. + u8 *descs_cpu;
  12269. + dma_addr_t descs_dma;
  12270. + unsigned int desc_size;
  12271. + unsigned int curr;
  12272. + unsigned int dirty;
  12273. + unsigned int size;
  12274. +};
  12275. +
  12276. +struct ag71xx_mdio {
  12277. + struct mii_bus *mii_bus;
  12278. + int mii_irq[PHY_MAX_ADDR];
  12279. + void __iomem *mdio_base;
  12280. + struct ag71xx_mdio_platform_data *pdata;
  12281. +};
  12282. +
  12283. +struct ag71xx_int_stats {
  12284. + unsigned long rx_pr;
  12285. + unsigned long rx_be;
  12286. + unsigned long rx_of;
  12287. + unsigned long tx_ps;
  12288. + unsigned long tx_be;
  12289. + unsigned long tx_ur;
  12290. + unsigned long total;
  12291. +};
  12292. +
  12293. +struct ag71xx_napi_stats {
  12294. + unsigned long napi_calls;
  12295. + unsigned long rx_count;
  12296. + unsigned long rx_packets;
  12297. + unsigned long rx_packets_max;
  12298. + unsigned long tx_count;
  12299. + unsigned long tx_packets;
  12300. + unsigned long tx_packets_max;
  12301. +
  12302. + unsigned long rx[AG71XX_NAPI_WEIGHT + 1];
  12303. + unsigned long tx[AG71XX_NAPI_WEIGHT + 1];
  12304. +};
  12305. +
  12306. +struct ag71xx_debug {
  12307. + struct dentry *debugfs_dir;
  12308. + struct dentry *debugfs_int_stats;
  12309. + struct dentry *debugfs_napi_stats;
  12310. +
  12311. + struct ag71xx_int_stats int_stats;
  12312. + struct ag71xx_napi_stats napi_stats;
  12313. +};
  12314. +
  12315. +struct ag71xx {
  12316. + void __iomem *mac_base;
  12317. + void __iomem *mii_ctrl;
  12318. +
  12319. + spinlock_t lock;
  12320. + struct platform_device *pdev;
  12321. + struct net_device *dev;
  12322. + struct napi_struct napi;
  12323. + u32 msg_enable;
  12324. +
  12325. + struct ag71xx_ring rx_ring;
  12326. + struct ag71xx_ring tx_ring;
  12327. +
  12328. + struct mii_bus *mii_bus;
  12329. + struct phy_device *phy_dev;
  12330. +
  12331. + unsigned int link;
  12332. + unsigned int speed;
  12333. + int duplex;
  12334. +
  12335. + struct work_struct restart_work;
  12336. + struct timer_list oom_timer;
  12337. +
  12338. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12339. + struct ag71xx_debug debug;
  12340. +#endif
  12341. +};
  12342. +
  12343. +extern struct ethtool_ops ag71xx_ethtool_ops;
  12344. +void ag71xx_link_adjust(struct ag71xx *ag);
  12345. +
  12346. +int ag71xx_mdio_driver_init(void) __init;
  12347. +void ag71xx_mdio_driver_exit(void);
  12348. +
  12349. +int ag71xx_phy_connect(struct ag71xx *ag);
  12350. +void ag71xx_phy_disconnect(struct ag71xx *ag);
  12351. +void ag71xx_phy_start(struct ag71xx *ag);
  12352. +void ag71xx_phy_stop(struct ag71xx *ag);
  12353. +
  12354. +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
  12355. +{
  12356. + return ag->pdev->dev.platform_data;
  12357. +}
  12358. +
  12359. +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
  12360. +{
  12361. + return ((desc->ctrl & DESC_EMPTY) != 0);
  12362. +}
  12363. +
  12364. +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
  12365. +{
  12366. + return (desc->ctrl & DESC_PKTLEN_M);
  12367. +}
  12368. +
  12369. +/* Register offsets */
  12370. +#define AG71XX_REG_MAC_CFG1 0x0000
  12371. +#define AG71XX_REG_MAC_CFG2 0x0004
  12372. +#define AG71XX_REG_MAC_IPG 0x0008
  12373. +#define AG71XX_REG_MAC_HDX 0x000c
  12374. +#define AG71XX_REG_MAC_MFL 0x0010
  12375. +#define AG71XX_REG_MII_CFG 0x0020
  12376. +#define AG71XX_REG_MII_CMD 0x0024
  12377. +#define AG71XX_REG_MII_ADDR 0x0028
  12378. +#define AG71XX_REG_MII_CTRL 0x002c
  12379. +#define AG71XX_REG_MII_STATUS 0x0030
  12380. +#define AG71XX_REG_MII_IND 0x0034
  12381. +#define AG71XX_REG_MAC_IFCTL 0x0038
  12382. +#define AG71XX_REG_MAC_ADDR1 0x0040
  12383. +#define AG71XX_REG_MAC_ADDR2 0x0044
  12384. +#define AG71XX_REG_FIFO_CFG0 0x0048
  12385. +#define AG71XX_REG_FIFO_CFG1 0x004c
  12386. +#define AG71XX_REG_FIFO_CFG2 0x0050
  12387. +#define AG71XX_REG_FIFO_CFG3 0x0054
  12388. +#define AG71XX_REG_FIFO_CFG4 0x0058
  12389. +#define AG71XX_REG_FIFO_CFG5 0x005c
  12390. +#define AG71XX_REG_FIFO_RAM0 0x0060
  12391. +#define AG71XX_REG_FIFO_RAM1 0x0064
  12392. +#define AG71XX_REG_FIFO_RAM2 0x0068
  12393. +#define AG71XX_REG_FIFO_RAM3 0x006c
  12394. +#define AG71XX_REG_FIFO_RAM4 0x0070
  12395. +#define AG71XX_REG_FIFO_RAM5 0x0074
  12396. +#define AG71XX_REG_FIFO_RAM6 0x0078
  12397. +#define AG71XX_REG_FIFO_RAM7 0x007c
  12398. +
  12399. +#define AG71XX_REG_TX_CTRL 0x0180
  12400. +#define AG71XX_REG_TX_DESC 0x0184
  12401. +#define AG71XX_REG_TX_STATUS 0x0188
  12402. +#define AG71XX_REG_RX_CTRL 0x018c
  12403. +#define AG71XX_REG_RX_DESC 0x0190
  12404. +#define AG71XX_REG_RX_STATUS 0x0194
  12405. +#define AG71XX_REG_INT_ENABLE 0x0198
  12406. +#define AG71XX_REG_INT_STATUS 0x019c
  12407. +
  12408. +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
  12409. +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
  12410. +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
  12411. +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
  12412. +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
  12413. +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
  12414. +#define MAC_CFG1_LB BIT(8) /* Loopback mode */
  12415. +#define MAC_CFG1_SR BIT(31) /* Soft Reset */
  12416. +
  12417. +#define MAC_CFG2_FDX BIT(0)
  12418. +#define MAC_CFG2_CRC_EN BIT(1)
  12419. +#define MAC_CFG2_PAD_CRC_EN BIT(2)
  12420. +#define MAC_CFG2_LEN_CHECK BIT(4)
  12421. +#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
  12422. +#define MAC_CFG2_IF_1000 BIT(9)
  12423. +#define MAC_CFG2_IF_10_100 BIT(8)
  12424. +
  12425. +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
  12426. +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
  12427. +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
  12428. +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
  12429. +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
  12430. +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
  12431. + | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
  12432. +
  12433. +#define FIFO_CFG0_ENABLE_SHIFT 8
  12434. +
  12435. +#define FIFO_CFG4_DE BIT(0) /* Drop Event */
  12436. +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
  12437. +#define FIFO_CFG4_FC BIT(2) /* False Carrier */
  12438. +#define FIFO_CFG4_CE BIT(3) /* Code Error */
  12439. +#define FIFO_CFG4_CR BIT(4) /* CRC error */
  12440. +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
  12441. +#define FIFO_CFG4_LO BIT(6) /* Length out of range */
  12442. +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
  12443. +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
  12444. +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
  12445. +#define FIFO_CFG4_DR BIT(10) /* Dribble */
  12446. +#define FIFO_CFG4_LE BIT(11) /* Long Event */
  12447. +#define FIFO_CFG4_CF BIT(12) /* Control Frame */
  12448. +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
  12449. +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
  12450. +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
  12451. +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
  12452. +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
  12453. +
  12454. +#define FIFO_CFG5_DE BIT(0) /* Drop Event */
  12455. +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
  12456. +#define FIFO_CFG5_FC BIT(2) /* False Carrier */
  12457. +#define FIFO_CFG5_CE BIT(3) /* Code Error */
  12458. +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
  12459. +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
  12460. +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
  12461. +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
  12462. +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
  12463. +#define FIFO_CFG5_DR BIT(9) /* Dribble */
  12464. +#define FIFO_CFG5_CF BIT(10) /* Control Frame */
  12465. +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
  12466. +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
  12467. +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
  12468. +#define FIFO_CFG5_LE BIT(14) /* Long Event */
  12469. +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
  12470. +#define FIFO_CFG5_16 BIT(16) /* unknown */
  12471. +#define FIFO_CFG5_17 BIT(17) /* unknown */
  12472. +#define FIFO_CFG5_SF BIT(18) /* Short Frame */
  12473. +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
  12474. +
  12475. +#define AG71XX_INT_TX_PS BIT(0)
  12476. +#define AG71XX_INT_TX_UR BIT(1)
  12477. +#define AG71XX_INT_TX_BE BIT(3)
  12478. +#define AG71XX_INT_RX_PR BIT(4)
  12479. +#define AG71XX_INT_RX_OF BIT(6)
  12480. +#define AG71XX_INT_RX_BE BIT(7)
  12481. +
  12482. +#define MAC_IFCTL_SPEED BIT(16)
  12483. +
  12484. +#define MII_CFG_CLK_DIV_4 0
  12485. +#define MII_CFG_CLK_DIV_6 2
  12486. +#define MII_CFG_CLK_DIV_8 3
  12487. +#define MII_CFG_CLK_DIV_10 4
  12488. +#define MII_CFG_CLK_DIV_14 5
  12489. +#define MII_CFG_CLK_DIV_20 6
  12490. +#define MII_CFG_CLK_DIV_28 7
  12491. +#define MII_CFG_RESET BIT(31)
  12492. +
  12493. +#define MII_CMD_WRITE 0x0
  12494. +#define MII_CMD_READ 0x1
  12495. +#define MII_ADDR_SHIFT 8
  12496. +#define MII_IND_BUSY BIT(0)
  12497. +#define MII_IND_INVALID BIT(2)
  12498. +
  12499. +#define TX_CTRL_TXE BIT(0) /* Tx Enable */
  12500. +
  12501. +#define TX_STATUS_PS BIT(0) /* Packet Sent */
  12502. +#define TX_STATUS_UR BIT(1) /* Tx Underrun */
  12503. +#define TX_STATUS_BE BIT(3) /* Bus Error */
  12504. +
  12505. +#define RX_CTRL_RXE BIT(0) /* Rx Enable */
  12506. +
  12507. +#define RX_STATUS_PR BIT(0) /* Packet Received */
  12508. +#define RX_STATUS_OF BIT(2) /* Rx Overflow */
  12509. +#define RX_STATUS_BE BIT(3) /* Bus Error */
  12510. +
  12511. +#define MII_CTRL_IF_MASK 3
  12512. +#define MII_CTRL_SPEED_SHIFT 4
  12513. +#define MII_CTRL_SPEED_MASK 3
  12514. +#define MII_CTRL_SPEED_10 0
  12515. +#define MII_CTRL_SPEED_100 1
  12516. +#define MII_CTRL_SPEED_1000 2
  12517. +
  12518. +static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
  12519. +{
  12520. + switch (reg) {
  12521. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  12522. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  12523. + break;
  12524. +
  12525. + default:
  12526. + BUG();
  12527. + }
  12528. +}
  12529. +
  12530. +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
  12531. +{
  12532. + ag71xx_check_reg_offset(ag, reg);
  12533. +
  12534. + __raw_writel(value, ag->mac_base + reg);
  12535. + /* flush write */
  12536. + (void) __raw_readl(ag->mac_base + reg);
  12537. +}
  12538. +
  12539. +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
  12540. +{
  12541. + ag71xx_check_reg_offset(ag, reg);
  12542. +
  12543. + return __raw_readl(ag->mac_base + reg);
  12544. +}
  12545. +
  12546. +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
  12547. +{
  12548. + void __iomem *r;
  12549. +
  12550. + ag71xx_check_reg_offset(ag, reg);
  12551. +
  12552. + r = ag->mac_base + reg;
  12553. + __raw_writel(__raw_readl(r) | mask, r);
  12554. + /* flush write */
  12555. + (void)__raw_readl(r);
  12556. +}
  12557. +
  12558. +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
  12559. +{
  12560. + void __iomem *r;
  12561. +
  12562. + ag71xx_check_reg_offset(ag, reg);
  12563. +
  12564. + r = ag->mac_base + reg;
  12565. + __raw_writel(__raw_readl(r) & ~mask, r);
  12566. + /* flush write */
  12567. + (void) __raw_readl(r);
  12568. +}
  12569. +
  12570. +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
  12571. +{
  12572. + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
  12573. +}
  12574. +
  12575. +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
  12576. +{
  12577. + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
  12578. +}
  12579. +
  12580. +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
  12581. +{
  12582. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12583. +
  12584. + if (pdata->is_ar724x)
  12585. + return;
  12586. +
  12587. + __raw_writel(value, ag->mii_ctrl);
  12588. +
  12589. + /* flush write */
  12590. + __raw_readl(ag->mii_ctrl);
  12591. +}
  12592. +
  12593. +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
  12594. +{
  12595. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12596. +
  12597. + if (pdata->is_ar724x)
  12598. + return 0xffffffff;
  12599. +
  12600. + return __raw_readl(ag->mii_ctrl);
  12601. +}
  12602. +
  12603. +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
  12604. + unsigned int mii_if)
  12605. +{
  12606. + u32 t;
  12607. +
  12608. + t = ag71xx_mii_ctrl_rr(ag);
  12609. + t &= ~(MII_CTRL_IF_MASK);
  12610. + t |= (mii_if & MII_CTRL_IF_MASK);
  12611. + ag71xx_mii_ctrl_wr(ag, t);
  12612. +}
  12613. +
  12614. +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
  12615. + unsigned int speed)
  12616. +{
  12617. + u32 t;
  12618. +
  12619. + t = ag71xx_mii_ctrl_rr(ag);
  12620. + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
  12621. + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
  12622. + ag71xx_mii_ctrl_wr(ag, t);
  12623. +}
  12624. +
  12625. +#ifdef CONFIG_AG71XX_AR8216_SUPPORT
  12626. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  12627. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12628. + int pktlen);
  12629. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12630. +{
  12631. + return ag71xx_get_pdata(ag)->has_ar8216;
  12632. +}
  12633. +#else
  12634. +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
  12635. + struct sk_buff *skb)
  12636. +{
  12637. +}
  12638. +
  12639. +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  12640. + struct sk_buff *skb,
  12641. + int pktlen)
  12642. +{
  12643. + return 0;
  12644. +}
  12645. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12646. +{
  12647. + return 0;
  12648. +}
  12649. +#endif
  12650. +
  12651. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12652. +int ag71xx_debugfs_root_init(void);
  12653. +void ag71xx_debugfs_root_exit(void);
  12654. +int ag71xx_debugfs_init(struct ag71xx *ag);
  12655. +void ag71xx_debugfs_exit(struct ag71xx *ag);
  12656. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status);
  12657. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx);
  12658. +#else
  12659. +static inline int ag71xx_debugfs_root_init(void) { return 0; }
  12660. +static inline void ag71xx_debugfs_root_exit(void) {}
  12661. +static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; }
  12662. +static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {}
  12663. +static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
  12664. + u32 status) {}
  12665. +static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
  12666. + int rx, int tx) {}
  12667. +#endif /* CONFIG_AG71XX_DEBUG_FS */
  12668. +
  12669. +#endif /* _AG71XX_H */
  12670. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c
  12671. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100
  12672. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-05-27 14:36:51.000000000 +0200
  12673. @@ -0,0 +1,44 @@
  12674. +/*
  12675. + * Atheros AR71xx built-in ethernet mac driver
  12676. + * Special support for the Atheros ar8216 switch chip
  12677. + *
  12678. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  12679. + *
  12680. + * Based on Atheros' AG7100 driver
  12681. + *
  12682. + * This program is free software; you can redistribute it and/or modify it
  12683. + * under the terms of the GNU General Public License version 2 as published
  12684. + * by the Free Software Foundation.
  12685. + */
  12686. +
  12687. +#include "ag71xx.h"
  12688. +
  12689. +#define AR8216_PACKET_TYPE_MASK 0xf
  12690. +#define AR8216_PACKET_TYPE_NORMAL 0
  12691. +
  12692. +#define AR8216_HEADER_LEN 2
  12693. +
  12694. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
  12695. +{
  12696. + skb_push(skb, AR8216_HEADER_LEN);
  12697. + skb->data[0] = 0x10;
  12698. + skb->data[1] = 0x80;
  12699. +}
  12700. +
  12701. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12702. + int pktlen)
  12703. +{
  12704. + u8 type;
  12705. +
  12706. + type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
  12707. + switch (type) {
  12708. + case AR8216_PACKET_TYPE_NORMAL:
  12709. + break;
  12710. +
  12711. + default:
  12712. + return -EINVAL;
  12713. + }
  12714. +
  12715. + skb_pull(skb, AR8216_HEADER_LEN);
  12716. + return 0;
  12717. +}
  12718. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c
  12719. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  12720. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-05-27 14:36:51.000000000 +0200
  12721. @@ -0,0 +1,197 @@
  12722. +/*
  12723. + * Atheros AR71xx built-in ethernet mac driver
  12724. + *
  12725. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12726. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12727. + *
  12728. + * Based on Atheros' AG7100 driver
  12729. + *
  12730. + * This program is free software; you can redistribute it and/or modify it
  12731. + * under the terms of the GNU General Public License version 2 as published
  12732. + * by the Free Software Foundation.
  12733. + */
  12734. +
  12735. +#include <linux/debugfs.h>
  12736. +
  12737. +#include "ag71xx.h"
  12738. +
  12739. +static struct dentry *ag71xx_debugfs_root;
  12740. +
  12741. +static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file)
  12742. +{
  12743. + file->private_data = inode->i_private;
  12744. + return 0;
  12745. +}
  12746. +
  12747. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status)
  12748. +{
  12749. + if (status)
  12750. + ag->debug.int_stats.total++;
  12751. + if (status & AG71XX_INT_TX_PS)
  12752. + ag->debug.int_stats.tx_ps++;
  12753. + if (status & AG71XX_INT_TX_UR)
  12754. + ag->debug.int_stats.tx_ur++;
  12755. + if (status & AG71XX_INT_TX_BE)
  12756. + ag->debug.int_stats.tx_be++;
  12757. + if (status & AG71XX_INT_RX_PR)
  12758. + ag->debug.int_stats.rx_pr++;
  12759. + if (status & AG71XX_INT_RX_OF)
  12760. + ag->debug.int_stats.rx_of++;
  12761. + if (status & AG71XX_INT_RX_BE)
  12762. + ag->debug.int_stats.rx_be++;
  12763. +}
  12764. +
  12765. +static ssize_t read_file_int_stats(struct file *file, char __user *user_buf,
  12766. + size_t count, loff_t *ppos)
  12767. +{
  12768. +#define PR_INT_STAT(_label, _field) \
  12769. + len += snprintf(buf + len, sizeof(buf) - len, \
  12770. + "%20s: %10lu\n", _label, ag->debug.int_stats._field);
  12771. +
  12772. + struct ag71xx *ag = file->private_data;
  12773. + char buf[256];
  12774. + unsigned int len = 0;
  12775. +
  12776. + PR_INT_STAT("TX Packet Sent", tx_ps);
  12777. + PR_INT_STAT("TX Underrun", tx_ur);
  12778. + PR_INT_STAT("TX Bus Error", tx_be);
  12779. + PR_INT_STAT("RX Packet Received", rx_pr);
  12780. + PR_INT_STAT("RX Overflow", rx_of);
  12781. + PR_INT_STAT("RX Bus Error", rx_be);
  12782. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  12783. + PR_INT_STAT("Total", total);
  12784. +
  12785. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  12786. +#undef PR_INT_STAT
  12787. +}
  12788. +
  12789. +static const struct file_operations ag71xx_fops_int_stats = {
  12790. + .open = ag71xx_debugfs_generic_open,
  12791. + .read = read_file_int_stats,
  12792. + .owner = THIS_MODULE
  12793. +};
  12794. +
  12795. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
  12796. +{
  12797. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  12798. +
  12799. + if (rx) {
  12800. + stats->rx_count++;
  12801. + stats->rx_packets += rx;
  12802. + if (rx <= AG71XX_NAPI_WEIGHT)
  12803. + stats->rx[rx]++;
  12804. + if (rx > stats->rx_packets_max)
  12805. + stats->rx_packets_max = rx;
  12806. + }
  12807. +
  12808. + if (tx) {
  12809. + stats->tx_count++;
  12810. + stats->tx_packets += tx;
  12811. + if (tx <= AG71XX_NAPI_WEIGHT)
  12812. + stats->tx[tx]++;
  12813. + if (tx > stats->tx_packets_max)
  12814. + stats->tx_packets_max = tx;
  12815. + }
  12816. +}
  12817. +
  12818. +static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf,
  12819. + size_t count, loff_t *ppos)
  12820. +{
  12821. + struct ag71xx *ag = file->private_data;
  12822. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  12823. + char buf[2048];
  12824. + unsigned int len = 0;
  12825. + unsigned long rx_avg = 0;
  12826. + unsigned long tx_avg = 0;
  12827. + int i;
  12828. +
  12829. + if (stats->rx_count)
  12830. + rx_avg = stats->rx_packets / stats->rx_count;
  12831. +
  12832. + if (stats->tx_count)
  12833. + tx_avg = stats->tx_packets / stats->tx_count;
  12834. +
  12835. + len += snprintf(buf + len, sizeof(buf) - len, "%3s %10s %10s\n",
  12836. + "len", "rx", "tx");
  12837. +
  12838. + for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++)
  12839. + len += snprintf(buf + len, sizeof(buf) - len,
  12840. + "%3d: %10lu %10lu\n",
  12841. + i, stats->rx[i], stats->tx[i]);
  12842. +
  12843. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  12844. +
  12845. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  12846. + "sum", stats->rx_count, stats->tx_count);
  12847. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  12848. + "avg", rx_avg, tx_avg);
  12849. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  12850. + "max", stats->rx_packets_max, stats->tx_packets_max);
  12851. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  12852. + "pkt", stats->rx_packets, stats->tx_packets);
  12853. +
  12854. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  12855. +}
  12856. +
  12857. +static const struct file_operations ag71xx_fops_napi_stats = {
  12858. + .open = ag71xx_debugfs_generic_open,
  12859. + .read = read_file_napi_stats,
  12860. + .owner = THIS_MODULE
  12861. +};
  12862. +
  12863. +void ag71xx_debugfs_exit(struct ag71xx *ag)
  12864. +{
  12865. + debugfs_remove(ag->debug.debugfs_napi_stats);
  12866. + debugfs_remove(ag->debug.debugfs_int_stats);
  12867. + debugfs_remove(ag->debug.debugfs_dir);
  12868. +}
  12869. +
  12870. +int ag71xx_debugfs_init(struct ag71xx *ag)
  12871. +{
  12872. + ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name,
  12873. + ag71xx_debugfs_root);
  12874. + if (!ag->debug.debugfs_dir)
  12875. + goto err;
  12876. +
  12877. + ag->debug.debugfs_int_stats =
  12878. + debugfs_create_file("int_stats",
  12879. + S_IRUGO,
  12880. + ag->debug.debugfs_dir,
  12881. + ag,
  12882. + &ag71xx_fops_int_stats);
  12883. + if (!ag->debug.debugfs_int_stats)
  12884. + goto err;
  12885. +
  12886. + ag->debug.debugfs_napi_stats =
  12887. + debugfs_create_file("napi_stats",
  12888. + S_IRUGO,
  12889. + ag->debug.debugfs_dir,
  12890. + ag,
  12891. + &ag71xx_fops_napi_stats);
  12892. + if (!ag->debug.debugfs_napi_stats)
  12893. + goto err;
  12894. +
  12895. + return 0;
  12896. +
  12897. + err:
  12898. + ag71xx_debugfs_exit(ag);
  12899. + return -ENOMEM;
  12900. +}
  12901. +
  12902. +int ag71xx_debugfs_root_init(void)
  12903. +{
  12904. + if (ag71xx_debugfs_root)
  12905. + return -EBUSY;
  12906. +
  12907. + ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
  12908. + if (!ag71xx_debugfs_root)
  12909. + return -ENOENT;
  12910. +
  12911. + return 0;
  12912. +}
  12913. +
  12914. +void ag71xx_debugfs_root_exit(void)
  12915. +{
  12916. + debugfs_remove(ag71xx_debugfs_root);
  12917. + ag71xx_debugfs_root = NULL;
  12918. +}
  12919. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c
  12920. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
  12921. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-05-27 14:36:51.000000000 +0200
  12922. @@ -0,0 +1,71 @@
  12923. +/*
  12924. + * Atheros AR71xx built-in ethernet mac driver
  12925. + *
  12926. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12927. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12928. + *
  12929. + * Based on Atheros' AG7100 driver
  12930. + *
  12931. + * This program is free software; you can redistribute it and/or modify it
  12932. + * under the terms of the GNU General Public License version 2 as published
  12933. + * by the Free Software Foundation.
  12934. + */
  12935. +
  12936. +#include "ag71xx.h"
  12937. +
  12938. +static int ag71xx_ethtool_get_settings(struct net_device *dev,
  12939. + struct ethtool_cmd *cmd)
  12940. +{
  12941. + struct ag71xx *ag = netdev_priv(dev);
  12942. + struct phy_device *phydev = ag->phy_dev;
  12943. +
  12944. + if (!phydev)
  12945. + return -ENODEV;
  12946. +
  12947. + return phy_ethtool_gset(phydev, cmd);
  12948. +}
  12949. +
  12950. +static int ag71xx_ethtool_set_settings(struct net_device *dev,
  12951. + struct ethtool_cmd *cmd)
  12952. +{
  12953. + struct ag71xx *ag = netdev_priv(dev);
  12954. + struct phy_device *phydev = ag->phy_dev;
  12955. +
  12956. + if (!phydev)
  12957. + return -ENODEV;
  12958. +
  12959. + return phy_ethtool_sset(phydev, cmd);
  12960. +}
  12961. +
  12962. +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev,
  12963. + struct ethtool_drvinfo *info)
  12964. +{
  12965. + struct ag71xx *ag = netdev_priv(dev);
  12966. +
  12967. + strcpy(info->driver, ag->pdev->dev.driver->name);
  12968. + strcpy(info->version, AG71XX_DRV_VERSION);
  12969. + strcpy(info->bus_info, dev_name(&ag->pdev->dev));
  12970. +}
  12971. +
  12972. +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev)
  12973. +{
  12974. + struct ag71xx *ag = netdev_priv(dev);
  12975. +
  12976. + return ag->msg_enable;
  12977. +}
  12978. +
  12979. +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level)
  12980. +{
  12981. + struct ag71xx *ag = netdev_priv(dev);
  12982. +
  12983. + ag->msg_enable = msg_level;
  12984. +}
  12985. +
  12986. +struct ethtool_ops ag71xx_ethtool_ops = {
  12987. + .set_settings = ag71xx_ethtool_set_settings,
  12988. + .get_settings = ag71xx_ethtool_get_settings,
  12989. + .get_drvinfo = ag71xx_ethtool_get_drvinfo,
  12990. + .get_msglevel = ag71xx_ethtool_get_msglevel,
  12991. + .set_msglevel = ag71xx_ethtool_set_msglevel,
  12992. + .get_link = ethtool_op_get_link,
  12993. +};
  12994. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c
  12995. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100
  12996. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-05-27 14:36:51.000000000 +0200
  12997. @@ -0,0 +1,1184 @@
  12998. +/*
  12999. + * Atheros AR71xx built-in ethernet mac driver
  13000. + *
  13001. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  13002. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  13003. + *
  13004. + * Based on Atheros' AG7100 driver
  13005. + *
  13006. + * This program is free software; you can redistribute it and/or modify it
  13007. + * under the terms of the GNU General Public License version 2 as published
  13008. + * by the Free Software Foundation.
  13009. + */
  13010. +
  13011. +#include "ag71xx.h"
  13012. +
  13013. +#define AG71XX_DEFAULT_MSG_ENABLE \
  13014. + ( NETIF_MSG_DRV \
  13015. + | NETIF_MSG_PROBE \
  13016. + | NETIF_MSG_LINK \
  13017. + | NETIF_MSG_TIMER \
  13018. + | NETIF_MSG_IFDOWN \
  13019. + | NETIF_MSG_IFUP \
  13020. + | NETIF_MSG_RX_ERR \
  13021. + | NETIF_MSG_TX_ERR )
  13022. +
  13023. +static int ag71xx_msg_level = -1;
  13024. +
  13025. +module_param_named(msg_level, ag71xx_msg_level, int, 0);
  13026. +MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
  13027. +
  13028. +static void ag71xx_dump_dma_regs(struct ag71xx *ag)
  13029. +{
  13030. + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n",
  13031. + ag->dev->name,
  13032. + ag71xx_rr(ag, AG71XX_REG_TX_CTRL),
  13033. + ag71xx_rr(ag, AG71XX_REG_TX_DESC),
  13034. + ag71xx_rr(ag, AG71XX_REG_TX_STATUS));
  13035. +
  13036. + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n",
  13037. + ag->dev->name,
  13038. + ag71xx_rr(ag, AG71XX_REG_RX_CTRL),
  13039. + ag71xx_rr(ag, AG71XX_REG_RX_DESC),
  13040. + ag71xx_rr(ag, AG71XX_REG_RX_STATUS));
  13041. +}
  13042. +
  13043. +static void ag71xx_dump_regs(struct ag71xx *ag)
  13044. +{
  13045. + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n",
  13046. + ag->dev->name,
  13047. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1),
  13048. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13049. + ag71xx_rr(ag, AG71XX_REG_MAC_IPG),
  13050. + ag71xx_rr(ag, AG71XX_REG_MAC_HDX),
  13051. + ag71xx_rr(ag, AG71XX_REG_MAC_MFL));
  13052. + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n",
  13053. + ag->dev->name,
  13054. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13055. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1),
  13056. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2));
  13057. + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n",
  13058. + ag->dev->name,
  13059. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13060. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13061. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13062. + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n",
  13063. + ag->dev->name,
  13064. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13065. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13066. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13067. +}
  13068. +
  13069. +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
  13070. +{
  13071. + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n",
  13072. + ag->dev->name, label, intr,
  13073. + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "",
  13074. + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "",
  13075. + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "",
  13076. + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "",
  13077. + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "",
  13078. + (intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
  13079. +}
  13080. +
  13081. +static void ag71xx_ring_free(struct ag71xx_ring *ring)
  13082. +{
  13083. + kfree(ring->buf);
  13084. +
  13085. + if (ring->descs_cpu)
  13086. + dma_free_coherent(NULL, ring->size * ring->desc_size,
  13087. + ring->descs_cpu, ring->descs_dma);
  13088. +}
  13089. +
  13090. +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
  13091. +{
  13092. + int err;
  13093. + int i;
  13094. +
  13095. + ring->desc_size = sizeof(struct ag71xx_desc);
  13096. + if (ring->desc_size % cache_line_size()) {
  13097. + DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
  13098. + ring, ring->desc_size,
  13099. + roundup(ring->desc_size, cache_line_size()));
  13100. + ring->desc_size = roundup(ring->desc_size, cache_line_size());
  13101. + }
  13102. +
  13103. + ring->descs_cpu = dma_alloc_coherent(NULL, size * ring->desc_size,
  13104. + &ring->descs_dma, GFP_ATOMIC);
  13105. + if (!ring->descs_cpu) {
  13106. + err = -ENOMEM;
  13107. + goto err;
  13108. + }
  13109. +
  13110. + ring->size = size;
  13111. +
  13112. + ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL);
  13113. + if (!ring->buf) {
  13114. + err = -ENOMEM;
  13115. + goto err;
  13116. + }
  13117. +
  13118. + for (i = 0; i < size; i++) {
  13119. + ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
  13120. + DBG("ag71xx: ring %p, desc %d at %p\n",
  13121. + ring, i, ring->buf[i].desc);
  13122. + }
  13123. +
  13124. + return 0;
  13125. +
  13126. + err:
  13127. + return err;
  13128. +}
  13129. +
  13130. +static void ag71xx_ring_tx_clean(struct ag71xx *ag)
  13131. +{
  13132. + struct ag71xx_ring *ring = &ag->tx_ring;
  13133. + struct net_device *dev = ag->dev;
  13134. +
  13135. + while (ring->curr != ring->dirty) {
  13136. + u32 i = ring->dirty % AG71XX_TX_RING_SIZE;
  13137. +
  13138. + if (!ag71xx_desc_empty(ring->buf[i].desc)) {
  13139. + ring->buf[i].desc->ctrl = 0;
  13140. + dev->stats.tx_errors++;
  13141. + }
  13142. +
  13143. + if (ring->buf[i].skb)
  13144. + dev_kfree_skb_any(ring->buf[i].skb);
  13145. +
  13146. + ring->buf[i].skb = NULL;
  13147. +
  13148. + ring->dirty++;
  13149. + }
  13150. +
  13151. + /* flush descriptors */
  13152. + wmb();
  13153. +
  13154. +}
  13155. +
  13156. +static void ag71xx_ring_tx_init(struct ag71xx *ag)
  13157. +{
  13158. + struct ag71xx_ring *ring = &ag->tx_ring;
  13159. + int i;
  13160. +
  13161. + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
  13162. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13163. + ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE));
  13164. +
  13165. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13166. + ring->buf[i].skb = NULL;
  13167. + }
  13168. +
  13169. + /* flush descriptors */
  13170. + wmb();
  13171. +
  13172. + ring->curr = 0;
  13173. + ring->dirty = 0;
  13174. +}
  13175. +
  13176. +static void ag71xx_ring_rx_clean(struct ag71xx *ag)
  13177. +{
  13178. + struct ag71xx_ring *ring = &ag->rx_ring;
  13179. + int i;
  13180. +
  13181. + if (!ring->buf)
  13182. + return;
  13183. +
  13184. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++)
  13185. + if (ring->buf[i].skb) {
  13186. + dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr,
  13187. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  13188. + kfree_skb(ring->buf[i].skb);
  13189. + }
  13190. +}
  13191. +
  13192. +static int ag71xx_rx_reserve(struct ag71xx *ag)
  13193. +{
  13194. + int reserve = 0;
  13195. +
  13196. + if (ag71xx_get_pdata(ag)->is_ar724x) {
  13197. + if (!ag71xx_has_ar8216(ag))
  13198. + reserve = 2;
  13199. +
  13200. + if (ag->phy_dev)
  13201. + reserve += 4 - (ag->phy_dev->pkt_align % 4);
  13202. +
  13203. + reserve %= 4;
  13204. + }
  13205. +
  13206. + return reserve + AG71XX_RX_PKT_RESERVE;
  13207. +}
  13208. +
  13209. +
  13210. +static int ag71xx_ring_rx_init(struct ag71xx *ag)
  13211. +{
  13212. + struct ag71xx_ring *ring = &ag->rx_ring;
  13213. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13214. + unsigned int i;
  13215. + int ret;
  13216. +
  13217. + ret = 0;
  13218. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13219. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13220. + ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE));
  13221. +
  13222. + DBG("ag71xx: RX desc at %p, next is %08x\n",
  13223. + ring->buf[i].desc,
  13224. + ring->buf[i].desc->next);
  13225. + }
  13226. +
  13227. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13228. + struct sk_buff *skb;
  13229. + dma_addr_t dma_addr;
  13230. +
  13231. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13232. + if (!skb) {
  13233. + ret = -ENOMEM;
  13234. + break;
  13235. + }
  13236. +
  13237. + skb->dev = ag->dev;
  13238. + skb_reserve(skb, reserve);
  13239. +
  13240. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13241. + AG71XX_RX_PKT_SIZE,
  13242. + DMA_FROM_DEVICE);
  13243. + ring->buf[i].skb = skb;
  13244. + ring->buf[i].dma_addr = dma_addr;
  13245. + ring->buf[i].desc->data = (u32) dma_addr;
  13246. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13247. + }
  13248. +
  13249. + /* flush descriptors */
  13250. + wmb();
  13251. +
  13252. + ring->curr = 0;
  13253. + ring->dirty = 0;
  13254. +
  13255. + return ret;
  13256. +}
  13257. +
  13258. +static int ag71xx_ring_rx_refill(struct ag71xx *ag)
  13259. +{
  13260. + struct ag71xx_ring *ring = &ag->rx_ring;
  13261. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13262. + unsigned int count;
  13263. +
  13264. + count = 0;
  13265. + for (; ring->curr - ring->dirty > 0; ring->dirty++) {
  13266. + unsigned int i;
  13267. +
  13268. + i = ring->dirty % AG71XX_RX_RING_SIZE;
  13269. +
  13270. + if (ring->buf[i].skb == NULL) {
  13271. + dma_addr_t dma_addr;
  13272. + struct sk_buff *skb;
  13273. +
  13274. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13275. + if (skb == NULL)
  13276. + break;
  13277. +
  13278. + skb_reserve(skb, reserve);
  13279. + skb->dev = ag->dev;
  13280. +
  13281. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13282. + AG71XX_RX_PKT_SIZE,
  13283. + DMA_FROM_DEVICE);
  13284. +
  13285. + ring->buf[i].skb = skb;
  13286. + ring->buf[i].dma_addr = dma_addr;
  13287. + ring->buf[i].desc->data = (u32) dma_addr;
  13288. + }
  13289. +
  13290. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13291. + count++;
  13292. + }
  13293. +
  13294. + /* flush descriptors */
  13295. + wmb();
  13296. +
  13297. + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count);
  13298. +
  13299. + return count;
  13300. +}
  13301. +
  13302. +static int ag71xx_rings_init(struct ag71xx *ag)
  13303. +{
  13304. + int ret;
  13305. +
  13306. + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
  13307. + if (ret)
  13308. + return ret;
  13309. +
  13310. + ag71xx_ring_tx_init(ag);
  13311. +
  13312. + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
  13313. + if (ret)
  13314. + return ret;
  13315. +
  13316. + ret = ag71xx_ring_rx_init(ag);
  13317. + return ret;
  13318. +}
  13319. +
  13320. +static void ag71xx_rings_cleanup(struct ag71xx *ag)
  13321. +{
  13322. + ag71xx_ring_rx_clean(ag);
  13323. + ag71xx_ring_free(&ag->rx_ring);
  13324. +
  13325. + ag71xx_ring_tx_clean(ag);
  13326. + ag71xx_ring_free(&ag->tx_ring);
  13327. +}
  13328. +
  13329. +static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
  13330. +{
  13331. + switch (ag->speed) {
  13332. + case SPEED_1000:
  13333. + return "1000";
  13334. + case SPEED_100:
  13335. + return "100";
  13336. + case SPEED_10:
  13337. + return "10";
  13338. + }
  13339. +
  13340. + return "?";
  13341. +}
  13342. +
  13343. +void ag71xx_link_adjust(struct ag71xx *ag)
  13344. +{
  13345. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13346. + u32 cfg2;
  13347. + u32 ifctl;
  13348. + u32 fifo5;
  13349. + u32 mii_speed;
  13350. +
  13351. + if (!ag->link) {
  13352. + netif_carrier_off(ag->dev);
  13353. + if (netif_msg_link(ag))
  13354. + printk(KERN_INFO "%s: link down\n", ag->dev->name);
  13355. + return;
  13356. + }
  13357. +
  13358. + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
  13359. + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
  13360. + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
  13361. +
  13362. + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
  13363. + ifctl &= ~(MAC_IFCTL_SPEED);
  13364. +
  13365. + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
  13366. + fifo5 &= ~FIFO_CFG5_BM;
  13367. +
  13368. + switch (ag->speed) {
  13369. + case SPEED_1000:
  13370. + mii_speed = MII_CTRL_SPEED_1000;
  13371. + cfg2 |= MAC_CFG2_IF_1000;
  13372. + fifo5 |= FIFO_CFG5_BM;
  13373. + break;
  13374. + case SPEED_100:
  13375. + mii_speed = MII_CTRL_SPEED_100;
  13376. + cfg2 |= MAC_CFG2_IF_10_100;
  13377. + ifctl |= MAC_IFCTL_SPEED;
  13378. + break;
  13379. + case SPEED_10:
  13380. + mii_speed = MII_CTRL_SPEED_10;
  13381. + cfg2 |= MAC_CFG2_IF_10_100;
  13382. + break;
  13383. + default:
  13384. + BUG();
  13385. + return;
  13386. + }
  13387. +
  13388. + if (pdata->is_ar91xx)
  13389. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
  13390. + else if (pdata->is_ar724x)
  13391. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3);
  13392. + else
  13393. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
  13394. +
  13395. + if (pdata->set_pll)
  13396. + pdata->set_pll(ag->speed);
  13397. +
  13398. + ag71xx_mii_ctrl_set_speed(ag, mii_speed);
  13399. +
  13400. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
  13401. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
  13402. + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
  13403. +
  13404. + netif_carrier_on(ag->dev);
  13405. + if (netif_msg_link(ag))
  13406. + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
  13407. + ag->dev->name,
  13408. + ag71xx_speed_str(ag),
  13409. + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half");
  13410. +
  13411. + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
  13412. + ag->dev->name,
  13413. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13414. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13415. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13416. +
  13417. + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
  13418. + ag->dev->name,
  13419. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13420. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13421. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13422. +
  13423. + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
  13424. + ag->dev->name,
  13425. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13426. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13427. + ag71xx_mii_ctrl_rr(ag));
  13428. +}
  13429. +
  13430. +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
  13431. +{
  13432. + u32 t;
  13433. +
  13434. + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
  13435. + | (((u32) mac[3]) << 8) | ((u32) mac[2]);
  13436. +
  13437. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
  13438. +
  13439. + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
  13440. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
  13441. +}
  13442. +
  13443. +static void ag71xx_dma_reset(struct ag71xx *ag)
  13444. +{
  13445. + u32 val;
  13446. + int i;
  13447. +
  13448. + ag71xx_dump_dma_regs(ag);
  13449. +
  13450. + /* stop RX and TX */
  13451. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  13452. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  13453. +
  13454. + /* clear descriptor addresses */
  13455. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
  13456. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
  13457. +
  13458. + /* clear pending RX/TX interrupts */
  13459. + for (i = 0; i < 256; i++) {
  13460. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  13461. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13462. + }
  13463. +
  13464. + /* clear pending errors */
  13465. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
  13466. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
  13467. +
  13468. + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  13469. + if (val)
  13470. + printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
  13471. + ag->dev->name, val);
  13472. +
  13473. + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  13474. +
  13475. + /* mask out reserved bits */
  13476. + val &= ~0xff000000;
  13477. +
  13478. + if (val)
  13479. + printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
  13480. + ag->dev->name, val);
  13481. +
  13482. + ag71xx_dump_dma_regs(ag);
  13483. +}
  13484. +
  13485. +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
  13486. + MAC_CFG1_SRX | MAC_CFG1_STX)
  13487. +
  13488. +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
  13489. +
  13490. +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
  13491. + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
  13492. + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
  13493. + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
  13494. + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
  13495. + FIFO_CFG4_VT)
  13496. +
  13497. +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
  13498. + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
  13499. + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
  13500. + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
  13501. + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
  13502. + FIFO_CFG5_17 | FIFO_CFG5_SF)
  13503. +
  13504. +static void ag71xx_hw_init(struct ag71xx *ag)
  13505. +{
  13506. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13507. +
  13508. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
  13509. + udelay(20);
  13510. +
  13511. + ar71xx_device_stop(pdata->reset_bit);
  13512. + mdelay(100);
  13513. + ar71xx_device_start(pdata->reset_bit);
  13514. + mdelay(100);
  13515. +
  13516. + /* setup MAC configuration registers */
  13517. + if (pdata->is_ar724x)
  13518. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1,
  13519. + MAC_CFG1_INIT | MAC_CFG1_TFC | MAC_CFG1_RFC);
  13520. + else
  13521. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
  13522. +
  13523. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
  13524. + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
  13525. +
  13526. + /* setup max frame length */
  13527. + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
  13528. +
  13529. + /* setup MII interface type */
  13530. + ag71xx_mii_ctrl_set_if(ag, pdata->mii_if);
  13531. +
  13532. + /* setup FIFO configuration registers */
  13533. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
  13534. + if (pdata->is_ar724x) {
  13535. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1);
  13536. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2);
  13537. + } else {
  13538. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
  13539. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
  13540. + }
  13541. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
  13542. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
  13543. +
  13544. + ag71xx_dma_reset(ag);
  13545. +}
  13546. +
  13547. +static void ag71xx_hw_start(struct ag71xx *ag)
  13548. +{
  13549. + /* start RX engine */
  13550. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  13551. +
  13552. + /* enable interrupts */
  13553. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
  13554. +}
  13555. +
  13556. +static void ag71xx_hw_stop(struct ag71xx *ag)
  13557. +{
  13558. + /* disable all interrupts */
  13559. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
  13560. +
  13561. + ag71xx_dma_reset(ag);
  13562. +}
  13563. +
  13564. +static int ag71xx_open(struct net_device *dev)
  13565. +{
  13566. + struct ag71xx *ag = netdev_priv(dev);
  13567. + int ret;
  13568. +
  13569. + ret = ag71xx_rings_init(ag);
  13570. + if (ret)
  13571. + goto err;
  13572. +
  13573. + napi_enable(&ag->napi);
  13574. +
  13575. + netif_carrier_off(dev);
  13576. + ag71xx_phy_start(ag);
  13577. +
  13578. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);
  13579. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma);
  13580. +
  13581. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  13582. +
  13583. + ag71xx_hw_start(ag);
  13584. +
  13585. + netif_start_queue(dev);
  13586. +
  13587. + return 0;
  13588. +
  13589. + err:
  13590. + ag71xx_rings_cleanup(ag);
  13591. + return ret;
  13592. +}
  13593. +
  13594. +static int ag71xx_stop(struct net_device *dev)
  13595. +{
  13596. + struct ag71xx *ag = netdev_priv(dev);
  13597. + unsigned long flags;
  13598. +
  13599. + netif_carrier_off(dev);
  13600. + ag71xx_phy_stop(ag);
  13601. +
  13602. + spin_lock_irqsave(&ag->lock, flags);
  13603. +
  13604. + netif_stop_queue(dev);
  13605. +
  13606. + ag71xx_hw_stop(ag);
  13607. +
  13608. + napi_disable(&ag->napi);
  13609. + del_timer_sync(&ag->oom_timer);
  13610. +
  13611. + spin_unlock_irqrestore(&ag->lock, flags);
  13612. +
  13613. + ag71xx_rings_cleanup(ag);
  13614. +
  13615. + return 0;
  13616. +}
  13617. +
  13618. +static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
  13619. + struct net_device *dev)
  13620. +{
  13621. + struct ag71xx *ag = netdev_priv(dev);
  13622. + struct ag71xx_ring *ring = &ag->tx_ring;
  13623. + struct ag71xx_desc *desc;
  13624. + dma_addr_t dma_addr;
  13625. + int i;
  13626. +
  13627. + i = ring->curr % AG71XX_TX_RING_SIZE;
  13628. + desc = ring->buf[i].desc;
  13629. +
  13630. + if (!ag71xx_desc_empty(desc))
  13631. + goto err_drop;
  13632. +
  13633. + if (ag71xx_has_ar8216(ag))
  13634. + ag71xx_add_ar8216_header(ag, skb);
  13635. +
  13636. + if (skb->len <= 0) {
  13637. + DBG("%s: packet len is too small\n", ag->dev->name);
  13638. + goto err_drop;
  13639. + }
  13640. +
  13641. + dma_addr = dma_map_single(&dev->dev, skb->data, skb->len,
  13642. + DMA_TO_DEVICE);
  13643. +
  13644. + ring->buf[i].skb = skb;
  13645. +
  13646. + /* setup descriptor fields */
  13647. + desc->data = (u32) dma_addr;
  13648. + desc->ctrl = (skb->len & DESC_PKTLEN_M);
  13649. +
  13650. + /* flush descriptor */
  13651. + wmb();
  13652. +
  13653. + ring->curr++;
  13654. + if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) {
  13655. + DBG("%s: tx queue full\n", ag->dev->name);
  13656. + netif_stop_queue(dev);
  13657. + }
  13658. +
  13659. + DBG("%s: packet injected into TX queue\n", ag->dev->name);
  13660. +
  13661. + /* enable TX engine */
  13662. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
  13663. +
  13664. + return NETDEV_TX_OK;
  13665. +
  13666. + err_drop:
  13667. + dev->stats.tx_dropped++;
  13668. +
  13669. + dev_kfree_skb(skb);
  13670. + return NETDEV_TX_OK;
  13671. +}
  13672. +
  13673. +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  13674. +{
  13675. + struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;
  13676. + struct ag71xx *ag = netdev_priv(dev);
  13677. + int ret;
  13678. +
  13679. + switch (cmd) {
  13680. + case SIOCETHTOOL:
  13681. + if (ag->phy_dev == NULL)
  13682. + break;
  13683. +
  13684. + spin_lock_irq(&ag->lock);
  13685. + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data);
  13686. + spin_unlock_irq(&ag->lock);
  13687. + return ret;
  13688. +
  13689. + case SIOCSIFHWADDR:
  13690. + if (copy_from_user
  13691. + (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
  13692. + return -EFAULT;
  13693. + return 0;
  13694. +
  13695. + case SIOCGIFHWADDR:
  13696. + if (copy_to_user
  13697. + (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
  13698. + return -EFAULT;
  13699. + return 0;
  13700. +
  13701. + case SIOCGMIIPHY:
  13702. + case SIOCGMIIREG:
  13703. + case SIOCSMIIREG:
  13704. + if (ag->phy_dev == NULL)
  13705. + break;
  13706. +
  13707. + return phy_mii_ioctl(ag->phy_dev, data, cmd);
  13708. +
  13709. + default:
  13710. + break;
  13711. + }
  13712. +
  13713. + return -EOPNOTSUPP;
  13714. +}
  13715. +
  13716. +static void ag71xx_oom_timer_handler(unsigned long data)
  13717. +{
  13718. + struct net_device *dev = (struct net_device *) data;
  13719. + struct ag71xx *ag = netdev_priv(dev);
  13720. +
  13721. + napi_schedule(&ag->napi);
  13722. +}
  13723. +
  13724. +static void ag71xx_tx_timeout(struct net_device *dev)
  13725. +{
  13726. + struct ag71xx *ag = netdev_priv(dev);
  13727. +
  13728. + if (netif_msg_tx_err(ag))
  13729. + printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
  13730. +
  13731. + schedule_work(&ag->restart_work);
  13732. +}
  13733. +
  13734. +static void ag71xx_restart_work_func(struct work_struct *work)
  13735. +{
  13736. + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
  13737. +
  13738. + ag71xx_stop(ag->dev);
  13739. + ag71xx_open(ag->dev);
  13740. +}
  13741. +
  13742. +static int ag71xx_tx_packets(struct ag71xx *ag)
  13743. +{
  13744. + struct ag71xx_ring *ring = &ag->tx_ring;
  13745. + int sent;
  13746. +
  13747. + DBG("%s: processing TX ring\n", ag->dev->name);
  13748. +
  13749. + sent = 0;
  13750. + while (ring->dirty != ring->curr) {
  13751. + unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE;
  13752. + struct ag71xx_desc *desc = ring->buf[i].desc;
  13753. + struct sk_buff *skb = ring->buf[i].skb;
  13754. +
  13755. + if (!ag71xx_desc_empty(desc))
  13756. + break;
  13757. +
  13758. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13759. +
  13760. + ag->dev->stats.tx_bytes += skb->len;
  13761. + ag->dev->stats.tx_packets++;
  13762. +
  13763. + dev_kfree_skb_any(skb);
  13764. + ring->buf[i].skb = NULL;
  13765. +
  13766. + ring->dirty++;
  13767. + sent++;
  13768. + }
  13769. +
  13770. + DBG("%s: %d packets sent out\n", ag->dev->name, sent);
  13771. +
  13772. + if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP)
  13773. + netif_wake_queue(ag->dev);
  13774. +
  13775. + return sent;
  13776. +}
  13777. +
  13778. +static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
  13779. +{
  13780. + struct net_device *dev = ag->dev;
  13781. + struct ag71xx_ring *ring = &ag->rx_ring;
  13782. + int done = 0;
  13783. +
  13784. + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n",
  13785. + dev->name, limit, ring->curr, ring->dirty);
  13786. +
  13787. + while (done < limit) {
  13788. + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
  13789. + struct ag71xx_desc *desc = ring->buf[i].desc;
  13790. + struct sk_buff *skb;
  13791. + int pktlen;
  13792. + int err = 0;
  13793. +
  13794. + if (ag71xx_desc_empty(desc))
  13795. + break;
  13796. +
  13797. + if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) {
  13798. + ag71xx_assert(0);
  13799. + break;
  13800. + }
  13801. +
  13802. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  13803. +
  13804. + skb = ring->buf[i].skb;
  13805. + pktlen = ag71xx_desc_pktlen(desc);
  13806. + pktlen -= ETH_FCS_LEN;
  13807. +
  13808. + dma_unmap_single(&dev->dev, ring->buf[i].dma_addr,
  13809. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  13810. +
  13811. + dev->last_rx = jiffies;
  13812. + dev->stats.rx_packets++;
  13813. + dev->stats.rx_bytes += pktlen;
  13814. +
  13815. + skb_put(skb, pktlen);
  13816. + if (ag71xx_has_ar8216(ag))
  13817. + err = ag71xx_remove_ar8216_header(ag, skb, pktlen);
  13818. +
  13819. + if (err) {
  13820. + dev->stats.rx_dropped++;
  13821. + kfree_skb(skb);
  13822. + } else {
  13823. + skb->dev = dev;
  13824. + skb->ip_summed = CHECKSUM_NONE;
  13825. + if (ag->phy_dev) {
  13826. + ag->phy_dev->netif_receive_skb(skb);
  13827. + } else {
  13828. + skb->protocol = eth_type_trans(skb, dev);
  13829. + netif_receive_skb(skb);
  13830. + }
  13831. + }
  13832. +
  13833. + ring->buf[i].skb = NULL;
  13834. + done++;
  13835. +
  13836. + ring->curr++;
  13837. + }
  13838. +
  13839. + ag71xx_ring_rx_refill(ag);
  13840. +
  13841. + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n",
  13842. + dev->name, ring->curr, ring->dirty, done);
  13843. +
  13844. + return done;
  13845. +}
  13846. +
  13847. +static int ag71xx_poll(struct napi_struct *napi, int limit)
  13848. +{
  13849. + struct ag71xx *ag = container_of(napi, struct ag71xx, napi);
  13850. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13851. + struct net_device *dev = ag->dev;
  13852. + struct ag71xx_ring *rx_ring;
  13853. + unsigned long flags;
  13854. + u32 status;
  13855. + int tx_done;
  13856. + int rx_done;
  13857. +
  13858. + pdata->ddr_flush();
  13859. + tx_done = ag71xx_tx_packets(ag);
  13860. +
  13861. + DBG("%s: processing RX ring\n", dev->name);
  13862. + rx_done = ag71xx_rx_packets(ag, limit);
  13863. +
  13864. + ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done);
  13865. +
  13866. + rx_ring = &ag->rx_ring;
  13867. + if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL)
  13868. + goto oom;
  13869. +
  13870. + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  13871. + if (unlikely(status & RX_STATUS_OF)) {
  13872. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
  13873. + dev->stats.rx_fifo_errors++;
  13874. +
  13875. + /* restart RX */
  13876. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  13877. + }
  13878. +
  13879. + if (rx_done < limit) {
  13880. + if (status & RX_STATUS_PR)
  13881. + goto more;
  13882. +
  13883. + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  13884. + if (status & TX_STATUS_PS)
  13885. + goto more;
  13886. +
  13887. + DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n",
  13888. + dev->name, rx_done, tx_done, limit);
  13889. +
  13890. + napi_complete(napi);
  13891. +
  13892. + /* enable interrupts */
  13893. + spin_lock_irqsave(&ag->lock, flags);
  13894. + ag71xx_int_enable(ag, AG71XX_INT_POLL);
  13895. + spin_unlock_irqrestore(&ag->lock, flags);
  13896. + return rx_done;
  13897. + }
  13898. +
  13899. + more:
  13900. + DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n",
  13901. + dev->name, rx_done, tx_done, limit);
  13902. + return rx_done;
  13903. +
  13904. + oom:
  13905. + if (netif_msg_rx_err(ag))
  13906. + printk(KERN_DEBUG "%s: out of memory\n", dev->name);
  13907. +
  13908. + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
  13909. + napi_complete(napi);
  13910. + return 0;
  13911. +}
  13912. +
  13913. +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
  13914. +{
  13915. + struct net_device *dev = dev_id;
  13916. + struct ag71xx *ag = netdev_priv(dev);
  13917. + u32 status;
  13918. +
  13919. + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
  13920. + ag71xx_dump_intr(ag, "raw", status);
  13921. +
  13922. + if (unlikely(!status))
  13923. + return IRQ_NONE;
  13924. +
  13925. + if (unlikely(status & AG71XX_INT_ERR)) {
  13926. + if (status & AG71XX_INT_TX_BE) {
  13927. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE);
  13928. + dev_err(&dev->dev, "TX BUS error\n");
  13929. + }
  13930. + if (status & AG71XX_INT_RX_BE) {
  13931. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE);
  13932. + dev_err(&dev->dev, "RX BUS error\n");
  13933. + }
  13934. + }
  13935. +
  13936. + if (likely(status & AG71XX_INT_POLL)) {
  13937. + ag71xx_int_disable(ag, AG71XX_INT_POLL);
  13938. + DBG("%s: enable polling mode\n", dev->name);
  13939. + napi_schedule(&ag->napi);
  13940. + }
  13941. +
  13942. + ag71xx_debugfs_update_int_stats(ag, status);
  13943. +
  13944. + return IRQ_HANDLED;
  13945. +}
  13946. +
  13947. +static void ag71xx_set_multicast_list(struct net_device *dev)
  13948. +{
  13949. + /* TODO */
  13950. +}
  13951. +
  13952. +#ifdef CONFIG_NET_POLL_CONTROLLER
  13953. +/*
  13954. + * Polling 'interrupt' - used by things like netconsole to send skbs
  13955. + * without having to re-enable interrupts. It's not called while
  13956. + * the interrupt routine is executing.
  13957. + */
  13958. +static void ag71xx_netpoll(struct net_device *dev)
  13959. +{
  13960. + disable_irq(dev->irq);
  13961. + ag71xx_interrupt(dev->irq, dev);
  13962. + enable_irq(dev->irq);
  13963. +}
  13964. +#endif
  13965. +
  13966. +static const struct net_device_ops ag71xx_netdev_ops = {
  13967. + .ndo_open = ag71xx_open,
  13968. + .ndo_stop = ag71xx_stop,
  13969. + .ndo_start_xmit = ag71xx_hard_start_xmit,
  13970. + .ndo_set_multicast_list = ag71xx_set_multicast_list,
  13971. + .ndo_do_ioctl = ag71xx_do_ioctl,
  13972. + .ndo_tx_timeout = ag71xx_tx_timeout,
  13973. + .ndo_change_mtu = eth_change_mtu,
  13974. + .ndo_set_mac_address = eth_mac_addr,
  13975. + .ndo_validate_addr = eth_validate_addr,
  13976. +#ifdef CONFIG_NET_POLL_CONTROLLER
  13977. + .ndo_poll_controller = ag71xx_netpoll,
  13978. +#endif
  13979. +};
  13980. +
  13981. +static int __init ag71xx_probe(struct platform_device *pdev)
  13982. +{
  13983. + struct net_device *dev;
  13984. + struct resource *res;
  13985. + struct ag71xx *ag;
  13986. + struct ag71xx_platform_data *pdata;
  13987. + int err;
  13988. +
  13989. + pdata = pdev->dev.platform_data;
  13990. + if (!pdata) {
  13991. + dev_err(&pdev->dev, "no platform data specified\n");
  13992. + err = -ENXIO;
  13993. + goto err_out;
  13994. + }
  13995. +
  13996. + if (pdata->mii_bus_dev == NULL) {
  13997. + dev_err(&pdev->dev, "no MII bus device specified\n");
  13998. + err = -EINVAL;
  13999. + goto err_out;
  14000. + }
  14001. +
  14002. + dev = alloc_etherdev(sizeof(*ag));
  14003. + if (!dev) {
  14004. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  14005. + err = -ENOMEM;
  14006. + goto err_out;
  14007. + }
  14008. +
  14009. + SET_NETDEV_DEV(dev, &pdev->dev);
  14010. +
  14011. + ag = netdev_priv(dev);
  14012. + ag->pdev = pdev;
  14013. + ag->dev = dev;
  14014. + ag->msg_enable = netif_msg_init(ag71xx_msg_level,
  14015. + AG71XX_DEFAULT_MSG_ENABLE);
  14016. + spin_lock_init(&ag->lock);
  14017. +
  14018. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base");
  14019. + if (!res) {
  14020. + dev_err(&pdev->dev, "no mac_base resource found\n");
  14021. + err = -ENXIO;
  14022. + goto err_out;
  14023. + }
  14024. +
  14025. + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14026. + if (!ag->mac_base) {
  14027. + dev_err(&pdev->dev, "unable to ioremap mac_base\n");
  14028. + err = -ENOMEM;
  14029. + goto err_free_dev;
  14030. + }
  14031. +
  14032. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl");
  14033. + if (!res) {
  14034. + dev_err(&pdev->dev, "no mii_ctrl resource found\n");
  14035. + err = -ENXIO;
  14036. + goto err_unmap_base;
  14037. + }
  14038. +
  14039. + ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1);
  14040. + if (!ag->mii_ctrl) {
  14041. + dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n");
  14042. + err = -ENOMEM;
  14043. + goto err_unmap_base;
  14044. + }
  14045. +
  14046. + dev->irq = platform_get_irq(pdev, 0);
  14047. + err = request_irq(dev->irq, ag71xx_interrupt,
  14048. + IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
  14049. + dev->name, dev);
  14050. + if (err) {
  14051. + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
  14052. + goto err_unmap_mii_ctrl;
  14053. + }
  14054. +
  14055. + dev->base_addr = (unsigned long)ag->mac_base;
  14056. + dev->netdev_ops = &ag71xx_netdev_ops;
  14057. + dev->ethtool_ops = &ag71xx_ethtool_ops;
  14058. +
  14059. + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
  14060. +
  14061. + init_timer(&ag->oom_timer);
  14062. + ag->oom_timer.data = (unsigned long) dev;
  14063. + ag->oom_timer.function = ag71xx_oom_timer_handler;
  14064. +
  14065. + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
  14066. +
  14067. + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
  14068. +
  14069. + err = register_netdev(dev);
  14070. + if (err) {
  14071. + dev_err(&pdev->dev, "unable to register net device\n");
  14072. + goto err_free_irq;
  14073. + }
  14074. +
  14075. + printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n",
  14076. + dev->name, dev->base_addr, dev->irq);
  14077. +
  14078. + ag71xx_dump_regs(ag);
  14079. +
  14080. + ag71xx_hw_init(ag);
  14081. +
  14082. + ag71xx_dump_regs(ag);
  14083. +
  14084. + err = ag71xx_phy_connect(ag);
  14085. + if (err)
  14086. + goto err_unregister_netdev;
  14087. +
  14088. + err = ag71xx_debugfs_init(ag);
  14089. + if (err)
  14090. + goto err_phy_disconnect;
  14091. +
  14092. + platform_set_drvdata(pdev, dev);
  14093. +
  14094. + return 0;
  14095. +
  14096. + err_phy_disconnect:
  14097. + ag71xx_phy_disconnect(ag);
  14098. + err_unregister_netdev:
  14099. + unregister_netdev(dev);
  14100. + err_free_irq:
  14101. + free_irq(dev->irq, dev);
  14102. + err_unmap_mii_ctrl:
  14103. + iounmap(ag->mii_ctrl);
  14104. + err_unmap_base:
  14105. + iounmap(ag->mac_base);
  14106. + err_free_dev:
  14107. + kfree(dev);
  14108. + err_out:
  14109. + platform_set_drvdata(pdev, NULL);
  14110. + return err;
  14111. +}
  14112. +
  14113. +static int __exit ag71xx_remove(struct platform_device *pdev)
  14114. +{
  14115. + struct net_device *dev = platform_get_drvdata(pdev);
  14116. +
  14117. + if (dev) {
  14118. + struct ag71xx *ag = netdev_priv(dev);
  14119. +
  14120. + ag71xx_debugfs_exit(ag);
  14121. + ag71xx_phy_disconnect(ag);
  14122. + unregister_netdev(dev);
  14123. + free_irq(dev->irq, dev);
  14124. + iounmap(ag->mii_ctrl);
  14125. + iounmap(ag->mac_base);
  14126. + kfree(dev);
  14127. + platform_set_drvdata(pdev, NULL);
  14128. + }
  14129. +
  14130. + return 0;
  14131. +}
  14132. +
  14133. +static struct platform_driver ag71xx_driver = {
  14134. + .probe = ag71xx_probe,
  14135. + .remove = __exit_p(ag71xx_remove),
  14136. + .driver = {
  14137. + .name = AG71XX_DRV_NAME,
  14138. + }
  14139. +};
  14140. +
  14141. +static int __init ag71xx_module_init(void)
  14142. +{
  14143. + int ret;
  14144. +
  14145. + ret = ag71xx_debugfs_root_init();
  14146. + if (ret)
  14147. + goto err_out;
  14148. +
  14149. + ret = ag71xx_mdio_driver_init();
  14150. + if (ret)
  14151. + goto err_debugfs_exit;
  14152. +
  14153. + ret = platform_driver_register(&ag71xx_driver);
  14154. + if (ret)
  14155. + goto err_mdio_exit;
  14156. +
  14157. + return 0;
  14158. +
  14159. + err_mdio_exit:
  14160. + ag71xx_mdio_driver_exit();
  14161. + err_debugfs_exit:
  14162. + ag71xx_debugfs_root_exit();
  14163. + err_out:
  14164. + return ret;
  14165. +}
  14166. +
  14167. +static void __exit ag71xx_module_exit(void)
  14168. +{
  14169. + platform_driver_unregister(&ag71xx_driver);
  14170. + ag71xx_mdio_driver_exit();
  14171. + ag71xx_debugfs_root_exit();
  14172. +}
  14173. +
  14174. +module_init(ag71xx_module_init);
  14175. +module_exit(ag71xx_module_exit);
  14176. +
  14177. +MODULE_VERSION(AG71XX_DRV_VERSION);
  14178. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  14179. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  14180. +MODULE_LICENSE("GPL v2");
  14181. +MODULE_ALIAS("platform:" AG71XX_DRV_NAME);
  14182. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c
  14183. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100
  14184. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-05-27 14:36:51.000000000 +0200
  14185. @@ -0,0 +1,243 @@
  14186. +/*
  14187. + * Atheros AR71xx built-in ethernet mac driver
  14188. + *
  14189. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14190. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14191. + *
  14192. + * Based on Atheros' AG7100 driver
  14193. + *
  14194. + * This program is free software; you can redistribute it and/or modify it
  14195. + * under the terms of the GNU General Public License version 2 as published
  14196. + * by the Free Software Foundation.
  14197. + */
  14198. +
  14199. +#include "ag71xx.h"
  14200. +
  14201. +#define AG71XX_MDIO_RETRY 1000
  14202. +#define AG71XX_MDIO_DELAY 5
  14203. +
  14204. +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg,
  14205. + u32 value)
  14206. +{
  14207. + void __iomem *r;
  14208. +
  14209. + r = am->mdio_base + reg;
  14210. + __raw_writel(value, r);
  14211. +
  14212. + /* flush write */
  14213. + (void) __raw_readl(r);
  14214. +}
  14215. +
  14216. +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg)
  14217. +{
  14218. + return __raw_readl(am->mdio_base + reg);
  14219. +}
  14220. +
  14221. +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
  14222. +{
  14223. + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n",
  14224. + am->mii_bus->name,
  14225. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG),
  14226. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD),
  14227. + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR));
  14228. + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n",
  14229. + am->mii_bus->name,
  14230. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL),
  14231. + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS),
  14232. + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
  14233. +}
  14234. +
  14235. +static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
  14236. +{
  14237. + int ret;
  14238. + int i;
  14239. +
  14240. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14241. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14242. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14243. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ);
  14244. +
  14245. + i = AG71XX_MDIO_RETRY;
  14246. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14247. + if (i-- == 0) {
  14248. + printk(KERN_ERR "%s: mii_read timed out\n",
  14249. + am->mii_bus->name);
  14250. + ret = 0xffff;
  14251. + goto out;
  14252. + }
  14253. + udelay(AG71XX_MDIO_DELAY);
  14254. + }
  14255. +
  14256. + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff;
  14257. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14258. +
  14259. + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
  14260. +
  14261. + out:
  14262. + return ret;
  14263. +}
  14264. +
  14265. +static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am,
  14266. + int addr, int reg, u16 val)
  14267. +{
  14268. + int i;
  14269. +
  14270. + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
  14271. +
  14272. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14273. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14274. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val);
  14275. +
  14276. + i = AG71XX_MDIO_RETRY;
  14277. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14278. + if (i-- == 0) {
  14279. + printk(KERN_ERR "%s: mii_write timed out\n",
  14280. + am->mii_bus->name);
  14281. + break;
  14282. + }
  14283. + udelay(AG71XX_MDIO_DELAY);
  14284. + }
  14285. +}
  14286. +
  14287. +static int ag71xx_mdio_reset(struct mii_bus *bus)
  14288. +{
  14289. + struct ag71xx_mdio *am = bus->priv;
  14290. + u32 t;
  14291. +
  14292. + if (am->pdata->is_ar7240)
  14293. + t = MII_CFG_CLK_DIV_6;
  14294. + else
  14295. + t = MII_CFG_CLK_DIV_28;
  14296. +
  14297. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
  14298. + udelay(100);
  14299. +
  14300. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t);
  14301. + udelay(100);
  14302. +
  14303. + return 0;
  14304. +}
  14305. +
  14306. +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
  14307. +{
  14308. + struct ag71xx_mdio *am = bus->priv;
  14309. +
  14310. + return ag71xx_mdio_mii_read(am, addr, reg);
  14311. +}
  14312. +
  14313. +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
  14314. +{
  14315. + struct ag71xx_mdio *am = bus->priv;
  14316. +
  14317. + ag71xx_mdio_mii_write(am, addr, reg, val);
  14318. + return 0;
  14319. +}
  14320. +
  14321. +static int __init ag71xx_mdio_probe(struct platform_device *pdev)
  14322. +{
  14323. + struct ag71xx_mdio_platform_data *pdata;
  14324. + struct ag71xx_mdio *am;
  14325. + struct resource *res;
  14326. + int i;
  14327. + int err;
  14328. +
  14329. + pdata = pdev->dev.platform_data;
  14330. + if (!pdata) {
  14331. + dev_err(&pdev->dev, "no platform data specified\n");
  14332. + return -EINVAL;
  14333. + }
  14334. +
  14335. + am = kzalloc(sizeof(*am), GFP_KERNEL);
  14336. + if (!am) {
  14337. + err = -ENOMEM;
  14338. + goto err_out;
  14339. + }
  14340. +
  14341. + am->pdata = pdata;
  14342. +
  14343. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  14344. + if (!res) {
  14345. + dev_err(&pdev->dev, "no iomem resource found\n");
  14346. + err = -ENXIO;
  14347. + goto err_out;
  14348. + }
  14349. +
  14350. + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14351. + if (!am->mdio_base) {
  14352. + dev_err(&pdev->dev, "unable to ioremap registers\n");
  14353. + err = -ENOMEM;
  14354. + goto err_free_mdio;
  14355. + }
  14356. +
  14357. + am->mii_bus = mdiobus_alloc();
  14358. + if (am->mii_bus == NULL) {
  14359. + err = -ENOMEM;
  14360. + goto err_iounmap;
  14361. + }
  14362. +
  14363. + am->mii_bus->name = "ag71xx_mdio";
  14364. + am->mii_bus->read = ag71xx_mdio_read;
  14365. + am->mii_bus->write = ag71xx_mdio_write;
  14366. + am->mii_bus->reset = ag71xx_mdio_reset;
  14367. + am->mii_bus->irq = am->mii_irq;
  14368. + am->mii_bus->priv = am;
  14369. + am->mii_bus->parent = &pdev->dev;
  14370. + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
  14371. + am->mii_bus->phy_mask = pdata->phy_mask;
  14372. +
  14373. + for (i = 0; i < PHY_MAX_ADDR; i++)
  14374. + am->mii_irq[i] = PHY_POLL;
  14375. +
  14376. + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0);
  14377. +
  14378. + err = mdiobus_register(am->mii_bus);
  14379. + if (err)
  14380. + goto err_free_bus;
  14381. +
  14382. + ag71xx_mdio_dump_regs(am);
  14383. +
  14384. + platform_set_drvdata(pdev, am);
  14385. + return 0;
  14386. +
  14387. + err_free_bus:
  14388. + mdiobus_free(am->mii_bus);
  14389. + err_iounmap:
  14390. + iounmap(am->mdio_base);
  14391. + err_free_mdio:
  14392. + kfree(am);
  14393. + err_out:
  14394. + return err;
  14395. +}
  14396. +
  14397. +static int __exit ag71xx_mdio_remove(struct platform_device *pdev)
  14398. +{
  14399. + struct ag71xx_mdio *am = platform_get_drvdata(pdev);
  14400. +
  14401. + if (am) {
  14402. + mdiobus_unregister(am->mii_bus);
  14403. + mdiobus_free(am->mii_bus);
  14404. + iounmap(am->mdio_base);
  14405. + kfree(am);
  14406. + platform_set_drvdata(pdev, NULL);
  14407. + }
  14408. +
  14409. + return 0;
  14410. +}
  14411. +
  14412. +static struct platform_driver ag71xx_mdio_driver = {
  14413. + .probe = ag71xx_mdio_probe,
  14414. + .remove = __exit_p(ag71xx_mdio_remove),
  14415. + .driver = {
  14416. + .name = "ag71xx-mdio",
  14417. + }
  14418. +};
  14419. +
  14420. +int ag71xx_mdio_driver_init(void)
  14421. +{
  14422. + return platform_driver_register(&ag71xx_mdio_driver);
  14423. +}
  14424. +
  14425. +void ag71xx_mdio_driver_exit(void)
  14426. +{
  14427. + platform_driver_unregister(&ag71xx_mdio_driver);
  14428. +}
  14429. diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c
  14430. --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100
  14431. +++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-05-27 14:36:51.000000000 +0200
  14432. @@ -0,0 +1,213 @@
  14433. +/*
  14434. + * Atheros AR71xx built-in ethernet mac driver
  14435. + *
  14436. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14437. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14438. + *
  14439. + * Based on Atheros' AG7100 driver
  14440. + *
  14441. + * This program is free software; you can redistribute it and/or modify it
  14442. + * under the terms of the GNU General Public License version 2 as published
  14443. + * by the Free Software Foundation.
  14444. + */
  14445. +
  14446. +#include "ag71xx.h"
  14447. +
  14448. +static void ag71xx_phy_link_adjust(struct net_device *dev)
  14449. +{
  14450. + struct ag71xx *ag = netdev_priv(dev);
  14451. + struct phy_device *phydev = ag->phy_dev;
  14452. + unsigned long flags;
  14453. + int status_change = 0;
  14454. +
  14455. + spin_lock_irqsave(&ag->lock, flags);
  14456. +
  14457. + if (phydev->link) {
  14458. + if (ag->duplex != phydev->duplex
  14459. + || ag->speed != phydev->speed) {
  14460. + status_change = 1;
  14461. + }
  14462. + }
  14463. +
  14464. + if (phydev->link != ag->link)
  14465. + status_change = 1;
  14466. +
  14467. + ag->link = phydev->link;
  14468. + ag->duplex = phydev->duplex;
  14469. + ag->speed = phydev->speed;
  14470. +
  14471. + if (status_change)
  14472. + ag71xx_link_adjust(ag);
  14473. +
  14474. + spin_unlock_irqrestore(&ag->lock, flags);
  14475. +}
  14476. +
  14477. +void ag71xx_phy_start(struct ag71xx *ag)
  14478. +{
  14479. + if (ag->phy_dev) {
  14480. + phy_start(ag->phy_dev);
  14481. + } else {
  14482. + ag->link = 1;
  14483. + ag71xx_link_adjust(ag);
  14484. + }
  14485. +}
  14486. +
  14487. +void ag71xx_phy_stop(struct ag71xx *ag)
  14488. +{
  14489. + if (ag->phy_dev) {
  14490. + phy_stop(ag->phy_dev);
  14491. + } else {
  14492. + ag->link = 0;
  14493. + ag71xx_link_adjust(ag);
  14494. + }
  14495. +}
  14496. +
  14497. +static int ag71xx_phy_connect_fixed(struct ag71xx *ag)
  14498. +{
  14499. + struct net_device *dev = ag->dev;
  14500. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14501. + int ret = 0;
  14502. +
  14503. + /* use fixed settings */
  14504. + switch (pdata->speed) {
  14505. + case SPEED_10:
  14506. + case SPEED_100:
  14507. + case SPEED_1000:
  14508. + break;
  14509. + default:
  14510. + printk(KERN_ERR "%s: invalid speed specified\n", dev->name);
  14511. + ret = -EINVAL;
  14512. + break;
  14513. + }
  14514. +
  14515. + printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name);
  14516. +
  14517. + ag->duplex = pdata->duplex;
  14518. + ag->speed = pdata->speed;
  14519. +
  14520. + return ret;
  14521. +}
  14522. +
  14523. +static int ag71xx_phy_connect_multi(struct ag71xx *ag)
  14524. +{
  14525. + struct net_device *dev = ag->dev;
  14526. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14527. + struct phy_device *phydev = NULL;
  14528. + int phy_addr;
  14529. + int ret = 0;
  14530. +
  14531. + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
  14532. + if (!(pdata->phy_mask & (1 << phy_addr)))
  14533. + continue;
  14534. +
  14535. + if (ag->mii_bus->phy_map[phy_addr] == NULL)
  14536. + continue;
  14537. +
  14538. + DBG("%s: PHY found at %s, uid=%08x\n",
  14539. + dev->name,
  14540. + dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),
  14541. + ag->mii_bus->phy_map[phy_addr]->phy_id);
  14542. +
  14543. + if (phydev == NULL)
  14544. + phydev = ag->mii_bus->phy_map[phy_addr];
  14545. + }
  14546. +
  14547. + if (!phydev) {
  14548. + printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",
  14549. + dev->name, pdata->phy_mask);
  14550. + return -ENODEV;
  14551. + }
  14552. +
  14553. + ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev),
  14554. + &ag71xx_phy_link_adjust, 0,
  14555. + pdata->phy_if_mode);
  14556. +
  14557. + if (IS_ERR(ag->phy_dev)) {
  14558. + printk(KERN_ERR "%s: could not connect to PHY at %s\n",
  14559. + dev->name, dev_name(&phydev->dev));
  14560. + return PTR_ERR(ag->phy_dev);
  14561. + }
  14562. +
  14563. + /* mask with MAC supported features */
  14564. + if (pdata->has_gbit)
  14565. + phydev->supported &= PHY_GBIT_FEATURES;
  14566. + else
  14567. + phydev->supported &= PHY_BASIC_FEATURES;
  14568. +
  14569. + phydev->advertising = phydev->supported;
  14570. +
  14571. + printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
  14572. + dev->name, dev_name(&phydev->dev),
  14573. + phydev->phy_id, phydev->drv->name);
  14574. +
  14575. + ag->link = 0;
  14576. + ag->speed = 0;
  14577. + ag->duplex = -1;
  14578. +
  14579. + return ret;
  14580. +}
  14581. +
  14582. +static int dev_is_class(struct device *dev, void *class)
  14583. +{
  14584. + if (dev->class != NULL && !strcmp(dev->class->name, class))
  14585. + return 1;
  14586. +
  14587. + return 0;
  14588. +}
  14589. +
  14590. +static struct device *dev_find_class(struct device *parent, char *class)
  14591. +{
  14592. + if (dev_is_class(parent, class)) {
  14593. + get_device(parent);
  14594. + return parent;
  14595. + }
  14596. +
  14597. + return device_find_child(parent, class, dev_is_class);
  14598. +}
  14599. +
  14600. +static struct mii_bus *dev_to_mii_bus(struct device *dev)
  14601. +{
  14602. + struct device *d;
  14603. +
  14604. + d = dev_find_class(dev, "mdio_bus");
  14605. + if (d != NULL) {
  14606. + struct mii_bus *bus;
  14607. +
  14608. + bus = to_mii_bus(d);
  14609. + put_device(d);
  14610. +
  14611. + return bus;
  14612. + }
  14613. +
  14614. + return NULL;
  14615. +}
  14616. +
  14617. +int ag71xx_phy_connect(struct ag71xx *ag)
  14618. +{
  14619. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14620. +
  14621. + ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev);
  14622. + if (ag->mii_bus == NULL) {
  14623. + printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n",
  14624. + ag->dev->name, dev_name(pdata->mii_bus_dev));
  14625. + return -ENODEV;
  14626. + }
  14627. +
  14628. + /* Reset the mdio bus explicitly */
  14629. + if (ag->mii_bus->reset) {
  14630. + mutex_lock(&ag->mii_bus->mdio_lock);
  14631. + ag->mii_bus->reset(ag->mii_bus);
  14632. + mutex_unlock(&ag->mii_bus->mdio_lock);
  14633. + }
  14634. +
  14635. + if (pdata->phy_mask)
  14636. + return ag71xx_phy_connect_multi(ag);
  14637. +
  14638. + return ag71xx_phy_connect_fixed(ag);
  14639. +}
  14640. +
  14641. +void ag71xx_phy_disconnect(struct ag71xx *ag)
  14642. +{
  14643. + if (ag->phy_dev)
  14644. + phy_disconnect(ag->phy_dev);
  14645. +}
  14646. diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig
  14647. --- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200
  14648. +++ linux-2.6.39/drivers/net/phy/Kconfig 2011-05-27 14:36:51.000000000 +0200
  14649. @@ -91,6 +91,10 @@
  14650. ---help---
  14651. Supports the KSZ9021, VSC8201, KS8001 PHYs.
  14652. +config IP175C_PHY
  14653. + tristate "Driver for IC+ IP175C/IP178C switches"
  14654. + select SWCONFIG
  14655. +
  14656. config FIXED_PHY
  14657. bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
  14658. depends on PHYLIB=y
  14659. diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c
  14660. --- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200
  14661. +++ linux-2.6.39/drivers/net/phy/phy.c 2011-05-27 14:36:51.000000000 +0200
  14662. @@ -297,6 +297,50 @@
  14663. }
  14664. EXPORT_SYMBOL(phy_ethtool_gset);
  14665. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  14666. +{
  14667. + u32 cmd;
  14668. + int tmp;
  14669. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  14670. + struct ethtool_value edata = { ETHTOOL_GLINK };
  14671. +
  14672. + if (get_user(cmd, (u32 *) useraddr))
  14673. + return -EFAULT;
  14674. +
  14675. + switch (cmd) {
  14676. + case ETHTOOL_GSET:
  14677. + phy_ethtool_gset(phydev, &ecmd);
  14678. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  14679. + return -EFAULT;
  14680. + return 0;
  14681. +
  14682. + case ETHTOOL_SSET:
  14683. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  14684. + return -EFAULT;
  14685. + return phy_ethtool_sset(phydev, &ecmd);
  14686. +
  14687. + case ETHTOOL_NWAY_RST:
  14688. + /* if autoneg is off, it's an error */
  14689. + tmp = phy_read(phydev, MII_BMCR);
  14690. + if (tmp & BMCR_ANENABLE) {
  14691. + tmp |= (BMCR_ANRESTART);
  14692. + phy_write(phydev, MII_BMCR, tmp);
  14693. + return 0;
  14694. + }
  14695. + return -EINVAL;
  14696. +
  14697. + case ETHTOOL_GLINK:
  14698. + edata.data = (phy_read(phydev,
  14699. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  14700. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  14701. + return -EFAULT;
  14702. + return 0;
  14703. + }
  14704. +
  14705. + return -EOPNOTSUPP;
  14706. +}
  14707. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  14708. +
  14709. /**
  14710. * phy_mii_ioctl - generic PHY MII ioctl interface
  14711. * @phydev: the phy_device struct
  14712. @@ -472,7 +516,7 @@
  14713. int idx;
  14714. idx = phy_find_setting(phydev->speed, phydev->duplex);
  14715. -
  14716. +
  14717. idx++;
  14718. idx = phy_find_valid(idx, phydev->supported);
  14719. diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c
  14720. --- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200
  14721. +++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-05-27 14:36:51.000000000 +0200
  14722. @@ -149,6 +149,19 @@
  14723. }
  14724. EXPORT_SYMBOL(phy_scan_fixups);
  14725. +static int generic_receive_skb(struct sk_buff *skb)
  14726. +{
  14727. + skb->protocol = eth_type_trans(skb, skb->dev);
  14728. + return netif_receive_skb(skb);
  14729. +}
  14730. +
  14731. +static int generic_rx(struct sk_buff *skb)
  14732. +{
  14733. + skb->protocol = eth_type_trans(skb, skb->dev);
  14734. + return netif_rx(skb);
  14735. +}
  14736. +
  14737. +
  14738. static struct phy_device* phy_device_create(struct mii_bus *bus,
  14739. int addr, int phy_id)
  14740. {
  14741. @@ -180,6 +193,8 @@
  14742. dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
  14743. dev->state = PHY_DOWN;
  14744. + dev->netif_receive_skb = &generic_receive_skb;
  14745. + dev->netif_rx = &generic_rx;
  14746. mutex_init(&dev->lock);
  14747. INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
  14748. diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig
  14749. --- linux-2.6.39.orig/drivers/spi/Kconfig 2011-05-19 06:06:34.000000000 +0200
  14750. +++ linux-2.6.39/drivers/spi/Kconfig 2011-05-27 14:36:51.000000000 +0200
  14751. @@ -67,6 +67,13 @@
  14752. This enables support for the SPI controller present on the
  14753. Atheros AR71XX/AR724X/AR913X SoCs.
  14754. +config SPI_AR71XX
  14755. + tristate "Atheros AR71xx SPI Controller"
  14756. + depends on SPI_MASTER && ATHEROS_AR71XX
  14757. + select SPI_BITBANG
  14758. + help
  14759. + This is the SPI contoller driver for Atheros AR71xx.
  14760. +
  14761. config SPI_ATMEL
  14762. tristate "Atmel SPI Controller"
  14763. depends on (ARCH_AT91 || AVR32)
  14764. diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile
  14765. --- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200
  14766. +++ linux-2.6.39/drivers/spi/Makefile 2011-05-27 14:36:51.000000000 +0200
  14767. @@ -11,6 +11,7 @@
  14768. # SPI master controller drivers (bus)
  14769. obj-$(CONFIG_SPI_ALTERA) += spi_altera.o
  14770. obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
  14771. +obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
  14772. obj-$(CONFIG_SPI_ATH79) += ath79_spi.o
  14773. obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
  14774. obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
  14775. diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c
  14776. --- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100
  14777. +++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-05-27 14:36:51.000000000 +0200
  14778. @@ -0,0 +1,282 @@
  14779. +/*
  14780. + * Atheros AP83 board specific SPI Controller driver
  14781. + *
  14782. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  14783. + *
  14784. + * This program is free software; you can redistribute it and/or modify
  14785. + * it under the terms of the GNU General Public License version 2 as
  14786. + * published by the Free Software Foundation.
  14787. + *
  14788. + */
  14789. +
  14790. +#include <linux/kernel.h>
  14791. +#include <linux/init.h>
  14792. +#include <linux/delay.h>
  14793. +#include <linux/spinlock.h>
  14794. +#include <linux/workqueue.h>
  14795. +#include <linux/platform_device.h>
  14796. +#include <linux/io.h>
  14797. +#include <linux/spi/spi.h>
  14798. +#include <linux/spi/spi_bitbang.h>
  14799. +#include <linux/bitops.h>
  14800. +#include <linux/gpio.h>
  14801. +
  14802. +#include <asm/mach-ar71xx/ar71xx.h>
  14803. +#include <asm/mach-ar71xx/platform.h>
  14804. +
  14805. +#define DRV_DESC "Atheros AP83 board SPI Controller driver"
  14806. +#define DRV_VERSION "0.1.0"
  14807. +#define DRV_NAME "ap83-spi"
  14808. +
  14809. +#define AP83_SPI_CLK_HIGH (1 << 23)
  14810. +#define AP83_SPI_CLK_LOW 0
  14811. +#define AP83_SPI_MOSI_HIGH (1 << 22)
  14812. +#define AP83_SPI_MOSI_LOW 0
  14813. +
  14814. +#define AP83_SPI_GPIO_CS 1
  14815. +#define AP83_SPI_GPIO_MISO 3
  14816. +
  14817. +struct ap83_spi {
  14818. + struct spi_bitbang bitbang;
  14819. + void __iomem *base;
  14820. + u32 addr;
  14821. +
  14822. + struct platform_device *pdev;
  14823. +};
  14824. +
  14825. +static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg)
  14826. +{
  14827. + return __raw_readl(sp->base + reg);
  14828. +}
  14829. +
  14830. +static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi)
  14831. +{
  14832. + return spi_master_get_devdata(spi->master);
  14833. +}
  14834. +
  14835. +static inline void setsck(struct spi_device *spi, int val)
  14836. +{
  14837. + struct ap83_spi *sp = spidev_to_sp(spi);
  14838. +
  14839. + if (val)
  14840. + sp->addr |= AP83_SPI_CLK_HIGH;
  14841. + else
  14842. + sp->addr &= ~AP83_SPI_CLK_HIGH;
  14843. +
  14844. + dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n",
  14845. + sp->addr, (val) ? "HIGH" : "LOW");
  14846. +
  14847. + ap83_spi_rr(sp, sp->addr);
  14848. +}
  14849. +
  14850. +static inline void setmosi(struct spi_device *spi, int val)
  14851. +{
  14852. + struct ap83_spi *sp = spidev_to_sp(spi);
  14853. +
  14854. + if (val)
  14855. + sp->addr |= AP83_SPI_MOSI_HIGH;
  14856. + else
  14857. + sp->addr &= ~AP83_SPI_MOSI_HIGH;
  14858. +
  14859. + dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n",
  14860. + sp->addr, (val) ? "HIGH" : "LOW");
  14861. +
  14862. + ap83_spi_rr(sp, sp->addr);
  14863. +}
  14864. +
  14865. +static inline u32 getmiso(struct spi_device *spi)
  14866. +{
  14867. + u32 ret;
  14868. +
  14869. + ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0;
  14870. + dev_dbg(&spi->dev, "get MISO: %d\n", ret);
  14871. +
  14872. + return ret;
  14873. +}
  14874. +
  14875. +static inline void do_spidelay(struct spi_device *spi, unsigned nsecs)
  14876. +{
  14877. + ndelay(nsecs);
  14878. +}
  14879. +
  14880. +static void ap83_spi_chipselect(struct spi_device *spi, int on)
  14881. +{
  14882. + struct ap83_spi *sp = spidev_to_sp(spi);
  14883. +
  14884. + dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1);
  14885. +
  14886. + if (on) {
  14887. + ar71xx_flash_acquire();
  14888. +
  14889. + sp->addr = 0;
  14890. + ap83_spi_rr(sp, sp->addr);
  14891. +
  14892. + gpio_set_value(AP83_SPI_GPIO_CS, 0);
  14893. + } else {
  14894. + gpio_set_value(AP83_SPI_GPIO_CS, 1);
  14895. + ar71xx_flash_release();
  14896. + }
  14897. +}
  14898. +
  14899. +#define spidelay(nsecs) \
  14900. + do { \
  14901. + /* Steal the spi_device pointer from our caller. \
  14902. + * The bitbang-API should probably get fixed here... */ \
  14903. + do_spidelay(spi, nsecs); \
  14904. + } while (0)
  14905. +
  14906. +#define EXPAND_BITBANG_TXRX
  14907. +#include <linux/spi/spi_bitbang.h>
  14908. +
  14909. +static u32 ap83_spi_txrx_mode0(struct spi_device *spi,
  14910. + unsigned nsecs, u32 word, u8 bits)
  14911. +{
  14912. + dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits);
  14913. + return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
  14914. +}
  14915. +
  14916. +static u32 ap83_spi_txrx_mode1(struct spi_device *spi,
  14917. + unsigned nsecs, u32 word, u8 bits)
  14918. +{
  14919. + dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits);
  14920. + return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
  14921. +}
  14922. +
  14923. +static u32 ap83_spi_txrx_mode2(struct spi_device *spi,
  14924. + unsigned nsecs, u32 word, u8 bits)
  14925. +{
  14926. + dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits);
  14927. + return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
  14928. +}
  14929. +
  14930. +static u32 ap83_spi_txrx_mode3(struct spi_device *spi,
  14931. + unsigned nsecs, u32 word, u8 bits)
  14932. +{
  14933. + dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits);
  14934. + return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
  14935. +}
  14936. +
  14937. +static int ap83_spi_probe(struct platform_device *pdev)
  14938. +{
  14939. + struct spi_master *master;
  14940. + struct ap83_spi *sp;
  14941. + struct ap83_spi_platform_data *pdata;
  14942. + struct resource *r;
  14943. + int ret;
  14944. +
  14945. + ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso");
  14946. + if (ret) {
  14947. + dev_err(&pdev->dev, "gpio request failed for MISO\n");
  14948. + return ret;
  14949. + }
  14950. +
  14951. + ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs");
  14952. + if (ret) {
  14953. + dev_err(&pdev->dev, "gpio request failed for CS\n");
  14954. + goto err_free_miso;
  14955. + }
  14956. +
  14957. + ret = gpio_direction_input(AP83_SPI_GPIO_MISO);
  14958. + if (ret) {
  14959. + dev_err(&pdev->dev, "unable to set direction of MISO\n");
  14960. + goto err_free_cs;
  14961. + }
  14962. +
  14963. + ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0);
  14964. + if (ret) {
  14965. + dev_err(&pdev->dev, "unable to set direction of CS\n");
  14966. + goto err_free_cs;
  14967. + }
  14968. +
  14969. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  14970. + if (master == NULL) {
  14971. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  14972. + return -ENOMEM;
  14973. + }
  14974. +
  14975. + sp = spi_master_get_devdata(master);
  14976. + platform_set_drvdata(pdev, sp);
  14977. +
  14978. + pdata = pdev->dev.platform_data;
  14979. +
  14980. + sp->bitbang.master = spi_master_get(master);
  14981. + sp->bitbang.chipselect = ap83_spi_chipselect;
  14982. + sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0;
  14983. + sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1;
  14984. + sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2;
  14985. + sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3;
  14986. +
  14987. + sp->bitbang.master->bus_num = pdev->id;
  14988. + sp->bitbang.master->num_chipselect = 1;
  14989. +
  14990. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  14991. + if (r == NULL) {
  14992. + ret = -ENOENT;
  14993. + goto err_spi_put;
  14994. + }
  14995. +
  14996. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  14997. + if (!sp->base) {
  14998. + ret = -ENXIO;
  14999. + goto err_spi_put;
  15000. + }
  15001. +
  15002. + ret = spi_bitbang_start(&sp->bitbang);
  15003. + if (!ret)
  15004. + goto err_unmap;
  15005. +
  15006. + dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start);
  15007. +
  15008. + return 0;
  15009. +
  15010. + err_unmap:
  15011. + iounmap(sp->base);
  15012. + err_spi_put:
  15013. + platform_set_drvdata(pdev, NULL);
  15014. + spi_master_put(sp->bitbang.master);
  15015. +
  15016. + err_free_cs:
  15017. + gpio_free(AP83_SPI_GPIO_CS);
  15018. + err_free_miso:
  15019. + gpio_free(AP83_SPI_GPIO_MISO);
  15020. + return ret;
  15021. +}
  15022. +
  15023. +static int ap83_spi_remove(struct platform_device *pdev)
  15024. +{
  15025. + struct ap83_spi *sp = platform_get_drvdata(pdev);
  15026. +
  15027. + spi_bitbang_stop(&sp->bitbang);
  15028. + iounmap(sp->base);
  15029. + platform_set_drvdata(pdev, NULL);
  15030. + spi_master_put(sp->bitbang.master);
  15031. +
  15032. + return 0;
  15033. +}
  15034. +
  15035. +static struct platform_driver ap83_spi_drv = {
  15036. + .probe = ap83_spi_probe,
  15037. + .remove = ap83_spi_remove,
  15038. + .driver = {
  15039. + .name = DRV_NAME,
  15040. + .owner = THIS_MODULE,
  15041. + },
  15042. +};
  15043. +
  15044. +static int __init ap83_spi_init(void)
  15045. +{
  15046. + return platform_driver_register(&ap83_spi_drv);
  15047. +}
  15048. +module_init(ap83_spi_init);
  15049. +
  15050. +static void __exit ap83_spi_exit(void)
  15051. +{
  15052. + platform_driver_unregister(&ap83_spi_drv);
  15053. +}
  15054. +module_exit(ap83_spi_exit);
  15055. +
  15056. +MODULE_ALIAS("platform:" DRV_NAME);
  15057. +MODULE_DESCRIPTION(DRV_DESC);
  15058. +MODULE_VERSION(DRV_VERSION);
  15059. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15060. +MODULE_LICENSE("GPL v2");
  15061. diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c
  15062. --- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  15063. +++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-05-27 14:36:51.000000000 +0200
  15064. @@ -0,0 +1,283 @@
  15065. +/*
  15066. + * Atheros AR71xx SPI Controller driver
  15067. + *
  15068. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  15069. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  15070. + *
  15071. + * This program is free software; you can redistribute it and/or modify
  15072. + * it under the terms of the GNU General Public License version 2 as
  15073. + * published by the Free Software Foundation.
  15074. + *
  15075. + */
  15076. +
  15077. +#include <linux/kernel.h>
  15078. +#include <linux/init.h>
  15079. +#include <linux/delay.h>
  15080. +#include <linux/spinlock.h>
  15081. +#include <linux/workqueue.h>
  15082. +#include <linux/platform_device.h>
  15083. +#include <linux/io.h>
  15084. +#include <linux/spi/spi.h>
  15085. +#include <linux/spi/spi_bitbang.h>
  15086. +#include <linux/bitops.h>
  15087. +
  15088. +#include <asm/mach-ar71xx/ar71xx.h>
  15089. +#include <asm/mach-ar71xx/platform.h>
  15090. +
  15091. +#define DRV_DESC "Atheros AR71xx SPI Controller driver"
  15092. +#define DRV_VERSION "0.2.4"
  15093. +#define DRV_NAME "ar71xx-spi"
  15094. +
  15095. +#undef PER_BIT_READ
  15096. +
  15097. +struct ar71xx_spi {
  15098. + struct spi_bitbang bitbang;
  15099. + u32 ioc_base;
  15100. + u32 reg_ctrl;
  15101. +
  15102. + void __iomem *base;
  15103. +
  15104. + struct platform_device *pdev;
  15105. + u32 (*get_ioc_base)(u8 chip_select, int cs_high,
  15106. + int is_on);
  15107. +};
  15108. +
  15109. +static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15110. +{
  15111. + return __raw_readl(sp->base + reg);
  15112. +}
  15113. +
  15114. +static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15115. +{
  15116. + __raw_writel(val, sp->base + reg);
  15117. +}
  15118. +
  15119. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15120. +{
  15121. + return spi_master_get_devdata(spi->master);
  15122. +}
  15123. +
  15124. +static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  15125. +{
  15126. + u32 ret;
  15127. +
  15128. + if (is_on == AR71XX_SPI_CS_INACTIVE)
  15129. + ret = SPI_IOC_CS_ALL;
  15130. + else
  15131. + ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select);
  15132. +
  15133. + return ret;
  15134. +}
  15135. +
  15136. +static void ar71xx_spi_chipselect(struct spi_device *spi, int value)
  15137. +{
  15138. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15139. + void __iomem *base = sp->base;
  15140. + u32 ioc_base;
  15141. +
  15142. + switch (value) {
  15143. + case BITBANG_CS_INACTIVE:
  15144. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15145. + (spi->mode & SPI_CS_HIGH) != 0,
  15146. + AR71XX_SPI_CS_INACTIVE);
  15147. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15148. + break;
  15149. +
  15150. + case BITBANG_CS_ACTIVE:
  15151. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15152. + (spi->mode & SPI_CS_HIGH) != 0,
  15153. + AR71XX_SPI_CS_ACTIVE);
  15154. +
  15155. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15156. + sp->ioc_base = ioc_base;
  15157. + break;
  15158. + }
  15159. +}
  15160. +
  15161. +static void ar71xx_spi_setup_regs(struct spi_device *spi)
  15162. +{
  15163. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15164. +
  15165. + /* enable GPIO mode */
  15166. + ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15167. +
  15168. + /* save CTRL register */
  15169. + sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL);
  15170. +
  15171. + /* TODO: setup speed? */
  15172. + ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15173. +}
  15174. +
  15175. +static void ar71xx_spi_restore_regs(struct spi_device *spi)
  15176. +{
  15177. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15178. +
  15179. + /* restore CTRL register */
  15180. + ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15181. + /* disable GPIO mode */
  15182. + ar71xx_spi_wr(sp, SPI_REG_FS, 0);
  15183. +}
  15184. +
  15185. +static int ar71xx_spi_setup(struct spi_device *spi)
  15186. +{
  15187. + int status;
  15188. +
  15189. + if (spi->bits_per_word > 32)
  15190. + return -EINVAL;
  15191. +
  15192. + if (!spi->controller_state)
  15193. + ar71xx_spi_setup_regs(spi);
  15194. +
  15195. + status = spi_bitbang_setup(spi);
  15196. + if (status && !spi->controller_state)
  15197. + ar71xx_spi_restore_regs(spi);
  15198. +
  15199. + return status;
  15200. +}
  15201. +
  15202. +static void ar71xx_spi_cleanup(struct spi_device *spi)
  15203. +{
  15204. + ar71xx_spi_restore_regs(spi);
  15205. + spi_bitbang_cleanup(spi);
  15206. +}
  15207. +
  15208. +static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15209. + u32 word, u8 bits)
  15210. +{
  15211. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15212. + void __iomem *base = sp->base;
  15213. + u32 ioc = sp->ioc_base;
  15214. + u32 ret;
  15215. +
  15216. + /* clock starts at inactive polarity */
  15217. + for (word <<= (32 - bits); likely(bits); bits--) {
  15218. + u32 out;
  15219. +
  15220. + if (word & (1 << 31))
  15221. + out = ioc | SPI_IOC_DO;
  15222. + else
  15223. + out = ioc & ~SPI_IOC_DO;
  15224. +
  15225. + /* setup MSB (to slave) on trailing edge */
  15226. + __raw_writel(out, base + SPI_REG_IOC);
  15227. +
  15228. + __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC);
  15229. +
  15230. + word <<= 1;
  15231. +
  15232. +#ifdef PER_BIT_READ
  15233. + /* sample MSB (from slave) on leading edge */
  15234. + ret = __raw_readl(base + SPI_REG_RDS);
  15235. + __raw_writel(out, base + SPI_REG_IOC);
  15236. +#endif
  15237. +
  15238. + }
  15239. +
  15240. +#ifndef PER_BIT_READ
  15241. + ret = __raw_readl(base + SPI_REG_RDS);
  15242. +#endif
  15243. + return ret;
  15244. +}
  15245. +
  15246. +static int ar71xx_spi_probe(struct platform_device *pdev)
  15247. +{
  15248. + struct spi_master *master;
  15249. + struct ar71xx_spi *sp;
  15250. + struct ar71xx_spi_platform_data *pdata;
  15251. + struct resource *r;
  15252. + int ret;
  15253. +
  15254. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15255. + if (master == NULL) {
  15256. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15257. + return -ENOMEM;
  15258. + }
  15259. +
  15260. + sp = spi_master_get_devdata(master);
  15261. + platform_set_drvdata(pdev, sp);
  15262. +
  15263. + pdata = pdev->dev.platform_data;
  15264. +
  15265. + master->setup = ar71xx_spi_setup;
  15266. + master->cleanup = ar71xx_spi_cleanup;
  15267. +
  15268. + sp->bitbang.master = spi_master_get(master);
  15269. + sp->bitbang.chipselect = ar71xx_spi_chipselect;
  15270. + sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
  15271. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15272. +
  15273. + sp->get_ioc_base = ar71xx_spi_get_ioc_base;
  15274. + if (pdata) {
  15275. + sp->bitbang.master->bus_num = pdata->bus_num;
  15276. + sp->bitbang.master->num_chipselect = pdata->num_chipselect;
  15277. + if (pdata->get_ioc_base)
  15278. + sp->get_ioc_base = pdata->get_ioc_base;
  15279. + } else {
  15280. + sp->bitbang.master->bus_num = 0;
  15281. + sp->bitbang.master->num_chipselect = 3;
  15282. + }
  15283. +
  15284. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15285. + if (r == NULL) {
  15286. + ret = -ENOENT;
  15287. + goto err1;
  15288. + }
  15289. +
  15290. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15291. + if (!sp->base) {
  15292. + ret = -ENXIO;
  15293. + goto err1;
  15294. + }
  15295. +
  15296. + ret = spi_bitbang_start(&sp->bitbang);
  15297. + if (!ret)
  15298. + return 0;
  15299. +
  15300. + iounmap(sp->base);
  15301. + err1:
  15302. + platform_set_drvdata(pdev, NULL);
  15303. + spi_master_put(sp->bitbang.master);
  15304. +
  15305. + return ret;
  15306. +}
  15307. +
  15308. +static int ar71xx_spi_remove(struct platform_device *pdev)
  15309. +{
  15310. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15311. +
  15312. + spi_bitbang_stop(&sp->bitbang);
  15313. + iounmap(sp->base);
  15314. + platform_set_drvdata(pdev, NULL);
  15315. + spi_master_put(sp->bitbang.master);
  15316. +
  15317. + return 0;
  15318. +}
  15319. +
  15320. +static struct platform_driver ar71xx_spi_drv = {
  15321. + .probe = ar71xx_spi_probe,
  15322. + .remove = ar71xx_spi_remove,
  15323. + .driver = {
  15324. + .name = DRV_NAME,
  15325. + .owner = THIS_MODULE,
  15326. + },
  15327. +};
  15328. +
  15329. +static int __init ar71xx_spi_init(void)
  15330. +{
  15331. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  15332. + return platform_driver_register(&ar71xx_spi_drv);
  15333. +}
  15334. +module_init(ar71xx_spi_init);
  15335. +
  15336. +static void __exit ar71xx_spi_exit(void)
  15337. +{
  15338. + platform_driver_unregister(&ar71xx_spi_drv);
  15339. +}
  15340. +module_exit(ar71xx_spi_exit);
  15341. +
  15342. +MODULE_ALIAS("platform:" DRV_NAME);
  15343. +MODULE_DESCRIPTION(DRV_DESC);
  15344. +MODULE_VERSION(DRV_VERSION);
  15345. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15346. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  15347. +MODULE_LICENSE("GPL v2");
  15348. diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44_spi.c
  15349. --- linux-2.6.39.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100
  15350. +++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-05-27 14:36:51.000000000 +0200
  15351. @@ -0,0 +1,299 @@
  15352. +/*
  15353. + * Atheros PB44 board SPI controller driver
  15354. + *
  15355. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15356. + *
  15357. + * This program is free software; you can redistribute it and/or modify
  15358. + * it under the terms of the GNU General Public License version 2 as
  15359. + * published by the Free Software Foundation.
  15360. + *
  15361. + */
  15362. +
  15363. +#include <linux/kernel.h>
  15364. +#include <linux/init.h>
  15365. +#include <linux/delay.h>
  15366. +#include <linux/spinlock.h>
  15367. +#include <linux/workqueue.h>
  15368. +#include <linux/platform_device.h>
  15369. +#include <linux/io.h>
  15370. +#include <linux/spi/spi.h>
  15371. +#include <linux/spi/spi_bitbang.h>
  15372. +#include <linux/bitops.h>
  15373. +#include <linux/gpio.h>
  15374. +
  15375. +#include <asm/mach-ar71xx/ar71xx.h>
  15376. +#include <asm/mach-ar71xx/platform.h>
  15377. +
  15378. +#define DRV_DESC "Atheros PB44 SPI Controller driver"
  15379. +#define DRV_VERSION "0.1.0"
  15380. +#define DRV_NAME "pb44-spi"
  15381. +
  15382. +#undef PER_BIT_READ
  15383. +
  15384. +struct ar71xx_spi {
  15385. + struct spi_bitbang bitbang;
  15386. + u32 ioc_base;
  15387. + u32 reg_ctrl;
  15388. +
  15389. + void __iomem *base;
  15390. +
  15391. + struct platform_device *pdev;
  15392. +};
  15393. +
  15394. +static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15395. +{
  15396. + return __raw_readl(sp->base + reg);
  15397. +}
  15398. +
  15399. +static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15400. +{
  15401. + __raw_writel(val, sp->base + reg);
  15402. +}
  15403. +
  15404. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15405. +{
  15406. + return spi_master_get_devdata(spi->master);
  15407. +}
  15408. +
  15409. +static void pb44_spi_chipselect(struct spi_device *spi, int is_active)
  15410. +{
  15411. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15412. + int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
  15413. +
  15414. + if (is_active) {
  15415. + /* set initial clock polarity */
  15416. + if (spi->mode & SPI_CPOL)
  15417. + sp->ioc_base |= SPI_IOC_CLK;
  15418. + else
  15419. + sp->ioc_base &= ~SPI_IOC_CLK;
  15420. +
  15421. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15422. + }
  15423. +
  15424. + if (spi->chip_select) {
  15425. + unsigned long gpio = (unsigned long) spi->controller_data;
  15426. +
  15427. + /* SPI is normally active-low */
  15428. + gpio_set_value(gpio, cs_high);
  15429. + } else {
  15430. + if (cs_high)
  15431. + sp->ioc_base |= SPI_IOC_CS0;
  15432. + else
  15433. + sp->ioc_base &= ~SPI_IOC_CS0;
  15434. +
  15435. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15436. + }
  15437. +
  15438. +}
  15439. +
  15440. +static int pb44_spi_setup_cs(struct spi_device *spi)
  15441. +{
  15442. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15443. +
  15444. + /* enable GPIO mode */
  15445. + pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15446. +
  15447. + /* save CTRL register */
  15448. + sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL);
  15449. + sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC);
  15450. +
  15451. + /* TODO: setup speed? */
  15452. + pb44_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15453. +
  15454. + if (spi->chip_select) {
  15455. + unsigned long gpio = (unsigned long) spi->controller_data;
  15456. + int status = 0;
  15457. +
  15458. + status = gpio_request(gpio, dev_name(&spi->dev));
  15459. + if (status)
  15460. + return status;
  15461. +
  15462. + status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
  15463. + if (status) {
  15464. + gpio_free(gpio);
  15465. + return status;
  15466. + }
  15467. + } else {
  15468. + if (spi->mode & SPI_CS_HIGH)
  15469. + sp->ioc_base |= SPI_IOC_CS0;
  15470. + else
  15471. + sp->ioc_base &= ~SPI_IOC_CS0;
  15472. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15473. + }
  15474. +
  15475. + return 0;
  15476. +}
  15477. +
  15478. +static void pb44_spi_cleanup_cs(struct spi_device *spi)
  15479. +{
  15480. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15481. +
  15482. + if (spi->chip_select) {
  15483. + unsigned long gpio = (unsigned long) spi->controller_data;
  15484. + gpio_free(gpio);
  15485. + }
  15486. +
  15487. + /* restore CTRL register */
  15488. + pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15489. + /* disable GPIO mode */
  15490. + pb44_spi_wr(sp, SPI_REG_FS, 0);
  15491. +}
  15492. +
  15493. +static int pb44_spi_setup(struct spi_device *spi)
  15494. +{
  15495. + int status = 0;
  15496. +
  15497. + if (spi->bits_per_word > 32)
  15498. + return -EINVAL;
  15499. +
  15500. + if (!spi->controller_state) {
  15501. + status = pb44_spi_setup_cs(spi);
  15502. + if (status)
  15503. + return status;
  15504. + }
  15505. +
  15506. + status = spi_bitbang_setup(spi);
  15507. + if (status && !spi->controller_state)
  15508. + pb44_spi_cleanup_cs(spi);
  15509. +
  15510. + return status;
  15511. +}
  15512. +
  15513. +static void pb44_spi_cleanup(struct spi_device *spi)
  15514. +{
  15515. + pb44_spi_cleanup_cs(spi);
  15516. + spi_bitbang_cleanup(spi);
  15517. +}
  15518. +
  15519. +static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15520. + u32 word, u8 bits)
  15521. +{
  15522. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15523. + u32 ioc = sp->ioc_base;
  15524. + u32 ret;
  15525. +
  15526. + /* clock starts at inactive polarity */
  15527. + for (word <<= (32 - bits); likely(bits); bits--) {
  15528. + u32 out;
  15529. +
  15530. + if (word & (1 << 31))
  15531. + out = ioc | SPI_IOC_DO;
  15532. + else
  15533. + out = ioc & ~SPI_IOC_DO;
  15534. +
  15535. + /* setup MSB (to slave) on trailing edge */
  15536. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15537. + pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK);
  15538. +
  15539. + word <<= 1;
  15540. +
  15541. +#ifdef PER_BIT_READ
  15542. + /* sample MSB (from slave) on leading edge */
  15543. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15544. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15545. +#endif
  15546. + }
  15547. +
  15548. +#ifndef PER_BIT_READ
  15549. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15550. +#endif
  15551. + return ret;
  15552. +}
  15553. +
  15554. +static int pb44_spi_probe(struct platform_device *pdev)
  15555. +{
  15556. + struct spi_master *master;
  15557. + struct ar71xx_spi *sp;
  15558. + struct ar71xx_spi_platform_data *pdata;
  15559. + struct resource *r;
  15560. + int ret;
  15561. +
  15562. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15563. + if (master == NULL) {
  15564. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15565. + return -ENOMEM;
  15566. + }
  15567. +
  15568. + sp = spi_master_get_devdata(master);
  15569. + platform_set_drvdata(pdev, sp);
  15570. +
  15571. + pdata = pdev->dev.platform_data;
  15572. +
  15573. + master->setup = pb44_spi_setup;
  15574. + master->cleanup = pb44_spi_cleanup;
  15575. + if (pdata) {
  15576. + master->bus_num = pdata->bus_num;
  15577. + master->num_chipselect = pdata->num_chipselect;
  15578. + } else {
  15579. + master->bus_num = 0;
  15580. + master->num_chipselect = 1;
  15581. + }
  15582. +
  15583. + sp->bitbang.master = spi_master_get(master);
  15584. + sp->bitbang.chipselect = pb44_spi_chipselect;
  15585. + sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0;
  15586. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15587. + sp->bitbang.flags = SPI_CS_HIGH;
  15588. +
  15589. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15590. + if (r == NULL) {
  15591. + ret = -ENOENT;
  15592. + goto err1;
  15593. + }
  15594. +
  15595. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15596. + if (!sp->base) {
  15597. + ret = -ENXIO;
  15598. + goto err1;
  15599. + }
  15600. +
  15601. + ret = spi_bitbang_start(&sp->bitbang);
  15602. + if (!ret)
  15603. + return 0;
  15604. +
  15605. + iounmap(sp->base);
  15606. + err1:
  15607. + platform_set_drvdata(pdev, NULL);
  15608. + spi_master_put(sp->bitbang.master);
  15609. +
  15610. + return ret;
  15611. +}
  15612. +
  15613. +static int pb44_spi_remove(struct platform_device *pdev)
  15614. +{
  15615. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15616. +
  15617. + spi_bitbang_stop(&sp->bitbang);
  15618. + iounmap(sp->base);
  15619. + platform_set_drvdata(pdev, NULL);
  15620. + spi_master_put(sp->bitbang.master);
  15621. +
  15622. + return 0;
  15623. +}
  15624. +
  15625. +static struct platform_driver pb44_spi_drv = {
  15626. + .probe = pb44_spi_probe,
  15627. + .remove = pb44_spi_remove,
  15628. + .driver = {
  15629. + .name = DRV_NAME,
  15630. + .owner = THIS_MODULE,
  15631. + },
  15632. +};
  15633. +
  15634. +static int __init pb44_spi_init(void)
  15635. +{
  15636. + return platform_driver_register(&pb44_spi_drv);
  15637. +}
  15638. +module_init(pb44_spi_init);
  15639. +
  15640. +static void __exit pb44_spi_exit(void)
  15641. +{
  15642. + platform_driver_unregister(&pb44_spi_drv);
  15643. +}
  15644. +module_exit(pb44_spi_exit);
  15645. +
  15646. +MODULE_ALIAS("platform:" DRV_NAME);
  15647. +MODULE_DESCRIPTION(DRV_DESC);
  15648. +MODULE_VERSION(DRV_VERSION);
  15649. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15650. +MODULE_LICENSE("GPL v2");
  15651. diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/spi_vsc7385.c
  15652. --- linux-2.6.39.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100
  15653. +++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-05-27 14:36:51.000000000 +0200
  15654. @@ -0,0 +1,620 @@
  15655. +/*
  15656. + * SPI driver for the Vitesse VSC7385 ethernet switch
  15657. + *
  15658. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15659. + *
  15660. + * Parts of this file are based on Atheros' 2.6.15 BSP
  15661. + *
  15662. + * This program is free software; you can redistribute it and/or modify it
  15663. + * under the terms of the GNU General Public License version 2 as published
  15664. + * by the Free Software Foundation.
  15665. + */
  15666. +
  15667. +#include <linux/types.h>
  15668. +#include <linux/kernel.h>
  15669. +#include <linux/init.h>
  15670. +#include <linux/module.h>
  15671. +#include <linux/delay.h>
  15672. +#include <linux/device.h>
  15673. +#include <linux/bitops.h>
  15674. +#include <linux/firmware.h>
  15675. +#include <linux/spi/spi.h>
  15676. +#include <linux/spi/vsc7385.h>
  15677. +
  15678. +#define DRV_NAME "spi-vsc7385"
  15679. +#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver"
  15680. +#define DRV_VERSION "0.1.0"
  15681. +
  15682. +#define VSC73XX_BLOCK_MAC 0x1
  15683. +#define VSC73XX_BLOCK_2 0x2
  15684. +#define VSC73XX_BLOCK_MII 0x3
  15685. +#define VSC73XX_BLOCK_4 0x4
  15686. +#define VSC73XX_BLOCK_5 0x5
  15687. +#define VSC73XX_BLOCK_SYSTEM 0x7
  15688. +
  15689. +#define VSC73XX_SUBBLOCK_PORT_0 0
  15690. +#define VSC73XX_SUBBLOCK_PORT_1 1
  15691. +#define VSC73XX_SUBBLOCK_PORT_2 2
  15692. +#define VSC73XX_SUBBLOCK_PORT_3 3
  15693. +#define VSC73XX_SUBBLOCK_PORT_4 4
  15694. +#define VSC73XX_SUBBLOCK_PORT_MAC 6
  15695. +
  15696. +/* MAC Block registers */
  15697. +#define VSC73XX_MAC_CFG 0x0
  15698. +#define VSC73XX_ADVPORTM 0x19
  15699. +#define VSC73XX_RXOCT 0x50
  15700. +#define VSC73XX_TXOCT 0x51
  15701. +#define VSC73XX_C_RX0 0x52
  15702. +#define VSC73XX_C_RX1 0x53
  15703. +#define VSC73XX_C_RX2 0x54
  15704. +#define VSC73XX_C_TX0 0x55
  15705. +#define VSC73XX_C_TX1 0x56
  15706. +#define VSC73XX_C_TX2 0x57
  15707. +#define VSC73XX_C_CFG 0x58
  15708. +
  15709. +/* MAC_CFG register bits */
  15710. +#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31)
  15711. +#define VSC73XX_MAC_CFG_PORT_RST (1 << 29)
  15712. +#define VSC73XX_MAC_CFG_TX_EN (1 << 28)
  15713. +#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27)
  15714. +#define VSC73XX_MAC_CFG_FDX (1 << 18)
  15715. +#define VSC73XX_MAC_CFG_GIGE (1 << 17)
  15716. +#define VSC73XX_MAC_CFG_RX_EN (1 << 16)
  15717. +#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15)
  15718. +#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14)
  15719. +#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13)
  15720. +#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6)
  15721. +#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5)
  15722. +#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4)
  15723. +#define VSC73XX_MAC_CFG_BIT2 (1 << 2)
  15724. +#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3)
  15725. +
  15726. +/* ADVPORTM register bits */
  15727. +#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7)
  15728. +#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6)
  15729. +#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5)
  15730. +#define VSC73XX_ADVPORTM_INV_GTX (1 << 4)
  15731. +#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3)
  15732. +#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2)
  15733. +#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1)
  15734. +#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0)
  15735. +
  15736. +/* MII Block registers */
  15737. +#define VSC73XX_MII_STAT 0x0
  15738. +#define VSC73XX_MII_CMD 0x1
  15739. +#define VSC73XX_MII_DATA 0x2
  15740. +
  15741. +/* System Block registers */
  15742. +#define VSC73XX_ICPU_SIPAD 0x01
  15743. +#define VSC73XX_ICPU_CLOCK_DELAY 0x05
  15744. +#define VSC73XX_ICPU_CTRL 0x10
  15745. +#define VSC73XX_ICPU_ADDR 0x11
  15746. +#define VSC73XX_ICPU_SRAM 0x12
  15747. +#define VSC73XX_ICPU_MBOX_VAL 0x15
  15748. +#define VSC73XX_ICPU_MBOX_SET 0x16
  15749. +#define VSC73XX_ICPU_MBOX_CLR 0x17
  15750. +#define VSC73XX_ICPU_CHIPID 0x18
  15751. +#define VSC73XX_ICPU_GPIO 0x34
  15752. +
  15753. +#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8)
  15754. +#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7)
  15755. +#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3)
  15756. +#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2)
  15757. +#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1)
  15758. +#define VSC73XX_ICPU_CTRL_SRST (1 << 0)
  15759. +
  15760. +#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12
  15761. +#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff
  15762. +#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28
  15763. +#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf
  15764. +#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385
  15765. +#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395
  15766. +
  15767. +#define VSC73XX_CMD_MODE_READ 0
  15768. +#define VSC73XX_CMD_MODE_WRITE 1
  15769. +#define VSC73XX_CMD_MODE_SHIFT 4
  15770. +#define VSC73XX_CMD_BLOCK_SHIFT 5
  15771. +#define VSC73XX_CMD_BLOCK_MASK 0x7
  15772. +#define VSC73XX_CMD_SUBBLOCK_MASK 0xf
  15773. +
  15774. +#define VSC7385_CLOCK_DELAY ((3 << 4) | 3)
  15775. +#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3)
  15776. +
  15777. +#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \
  15778. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  15779. + VSC73XX_ICPU_CTRL_EXT_ACC_EN)
  15780. +
  15781. +#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \
  15782. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  15783. + VSC73XX_ICPU_CTRL_CLK_EN | \
  15784. + VSC73XX_ICPU_CTRL_SRST)
  15785. +
  15786. +#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \
  15787. + VSC73XX_ADVPORTM_EXC_COL_CONT | \
  15788. + VSC73XX_ADVPORTM_EXT_PORT | \
  15789. + VSC73XX_ADVPORTM_INV_GTX | \
  15790. + VSC73XX_ADVPORTM_ENA_GTX | \
  15791. + VSC73XX_ADVPORTM_DDR_MODE | \
  15792. + VSC73XX_ADVPORTM_IO_LOOPBACK | \
  15793. + VSC73XX_ADVPORTM_HOST_LOOPBACK)
  15794. +
  15795. +#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \
  15796. + VSC73XX_ADVPORTM_ENA_GTX | \
  15797. + VSC73XX_ADVPORTM_DDR_MODE)
  15798. +
  15799. +#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \
  15800. + VSC73XX_MAC_CFG_MAC_RX_RST | \
  15801. + VSC73XX_MAC_CFG_MAC_TX_RST)
  15802. +
  15803. +#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \
  15804. + VSC73XX_MAC_CFG_FDX | \
  15805. + VSC73XX_MAC_CFG_GIGE | \
  15806. + VSC73XX_MAC_CFG_RX_EN)
  15807. +
  15808. +#define VSC73XX_RESET_DELAY 100
  15809. +
  15810. +struct vsc7385 {
  15811. + struct spi_device *spi;
  15812. + struct mutex lock;
  15813. + struct vsc7385_platform_data *pdata;
  15814. +};
  15815. +
  15816. +static int vsc7385_is_addr_valid(u8 block, u8 subblock)
  15817. +{
  15818. + switch (block) {
  15819. + case VSC73XX_BLOCK_MAC:
  15820. + switch (subblock) {
  15821. + case 0 ... 4:
  15822. + case 6:
  15823. + return 1;
  15824. + }
  15825. + break;
  15826. +
  15827. + case VSC73XX_BLOCK_2:
  15828. + case VSC73XX_BLOCK_SYSTEM:
  15829. + switch (subblock) {
  15830. + case 0:
  15831. + return 1;
  15832. + }
  15833. + break;
  15834. +
  15835. + case VSC73XX_BLOCK_MII:
  15836. + case VSC73XX_BLOCK_4:
  15837. + case VSC73XX_BLOCK_5:
  15838. + switch (subblock) {
  15839. + case 0 ... 1:
  15840. + return 1;
  15841. + }
  15842. + break;
  15843. + }
  15844. +
  15845. + return 0;
  15846. +}
  15847. +
  15848. +static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock)
  15849. +{
  15850. + u8 ret;
  15851. +
  15852. + ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT;
  15853. + ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT;
  15854. + ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK;
  15855. +
  15856. + return ret;
  15857. +}
  15858. +
  15859. +static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  15860. + u32 *value)
  15861. +{
  15862. + u8 cmd[4];
  15863. + u8 buf[4];
  15864. + struct spi_transfer t[2];
  15865. + struct spi_message m;
  15866. + int err;
  15867. +
  15868. + if (!vsc7385_is_addr_valid(block, subblock))
  15869. + return -EINVAL;
  15870. +
  15871. + spi_message_init(&m);
  15872. +
  15873. + memset(&t, 0, sizeof(t));
  15874. +
  15875. + t[0].tx_buf = cmd;
  15876. + t[0].len = sizeof(cmd);
  15877. + spi_message_add_tail(&t[0], &m);
  15878. +
  15879. + t[1].rx_buf = buf;
  15880. + t[1].len = sizeof(buf);
  15881. + spi_message_add_tail(&t[1], &m);
  15882. +
  15883. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock);
  15884. + cmd[1] = reg;
  15885. + cmd[2] = 0;
  15886. + cmd[3] = 0;
  15887. +
  15888. + mutex_lock(&vsc->lock);
  15889. + err = spi_sync(vsc->spi, &m);
  15890. + mutex_unlock(&vsc->lock);
  15891. +
  15892. + if (err)
  15893. + return err;
  15894. +
  15895. + *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) |
  15896. + (((u32) buf[2]) << 8) | ((u32) buf[3]);
  15897. +
  15898. + return 0;
  15899. +}
  15900. +
  15901. +
  15902. +static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  15903. + u32 value)
  15904. +{
  15905. + u8 cmd[2];
  15906. + u8 buf[4];
  15907. + struct spi_transfer t[2];
  15908. + struct spi_message m;
  15909. + int err;
  15910. +
  15911. + if (!vsc7385_is_addr_valid(block, subblock))
  15912. + return -EINVAL;
  15913. +
  15914. + spi_message_init(&m);
  15915. +
  15916. + memset(&t, 0, sizeof(t));
  15917. +
  15918. + t[0].tx_buf = cmd;
  15919. + t[0].len = sizeof(cmd);
  15920. + spi_message_add_tail(&t[0], &m);
  15921. +
  15922. + t[1].tx_buf = buf;
  15923. + t[1].len = sizeof(buf);
  15924. + spi_message_add_tail(&t[1], &m);
  15925. +
  15926. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock);
  15927. + cmd[1] = reg;
  15928. +
  15929. + buf[0] = (value >> 24) & 0xff;
  15930. + buf[1] = (value >> 16) & 0xff;
  15931. + buf[2] = (value >> 8) & 0xff;
  15932. + buf[3] = value & 0xff;
  15933. +
  15934. + mutex_lock(&vsc->lock);
  15935. + err = spi_sync(vsc->spi, &m);
  15936. + mutex_unlock(&vsc->lock);
  15937. +
  15938. + return err;
  15939. +}
  15940. +
  15941. +static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block,
  15942. + u8 subblock, u8 reg, u32 value,
  15943. + u32 read_mask, u32 read_val)
  15944. +{
  15945. + struct spi_device *spi = vsc->spi;
  15946. + u32 t;
  15947. + int err;
  15948. +
  15949. + err = vsc7385_write(vsc, block, subblock, reg, value);
  15950. + if (err)
  15951. + return err;
  15952. +
  15953. + err = vsc7385_read(vsc, block, subblock, reg, &t);
  15954. + if (err)
  15955. + return err;
  15956. +
  15957. + if ((t & read_mask) != read_val) {
  15958. + dev_err(&spi->dev, "register write error\n");
  15959. + return -EIO;
  15960. + }
  15961. +
  15962. + return 0;
  15963. +}
  15964. +
  15965. +static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val)
  15966. +{
  15967. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  15968. + VSC73XX_ICPU_CLOCK_DELAY, val);
  15969. +}
  15970. +
  15971. +static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val)
  15972. +{
  15973. + return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  15974. + VSC73XX_ICPU_CLOCK_DELAY, val);
  15975. +}
  15976. +
  15977. +static inline int vsc7385_icpu_stop(struct vsc7385 *vsc)
  15978. +{
  15979. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  15980. + VSC73XX_ICPU_CTRL_STOP);
  15981. +}
  15982. +
  15983. +static inline int vsc7385_icpu_start(struct vsc7385 *vsc)
  15984. +{
  15985. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  15986. + VSC73XX_ICPU_CTRL_START);
  15987. +}
  15988. +
  15989. +static inline int vsc7385_icpu_reset(struct vsc7385 *vsc)
  15990. +{
  15991. + int rc;
  15992. +
  15993. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR,
  15994. + 0x0000);
  15995. + if (rc)
  15996. + dev_err(&vsc->spi->dev,
  15997. + "could not reset microcode, err=%d\n", rc);
  15998. +
  15999. + return rc;
  16000. +}
  16001. +
  16002. +static int vsc7385_upload_ucode(struct vsc7385 *vsc)
  16003. +{
  16004. + struct spi_device *spi = vsc->spi;
  16005. + const struct firmware *firmware;
  16006. + char *ucode_name;
  16007. + unsigned char *dp;
  16008. + unsigned int curVal;
  16009. + int i;
  16010. + int diffs;
  16011. + int rc;
  16012. +
  16013. + ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name
  16014. + : "vsc7385_ucode.bin";
  16015. + rc = request_firmware(&firmware, ucode_name, &spi->dev);
  16016. + if (rc) {
  16017. + dev_err(&spi->dev, "request_firmware failed, err=%d\n",
  16018. + rc);
  16019. + return rc;
  16020. + }
  16021. +
  16022. + rc = vsc7385_icpu_stop(vsc);
  16023. + if (rc)
  16024. + goto out;
  16025. +
  16026. + rc = vsc7385_icpu_reset(vsc);
  16027. + if (rc)
  16028. + goto out;
  16029. +
  16030. + dev_info(&spi->dev, "uploading microcode...\n");
  16031. +
  16032. + dp = (unsigned char *) firmware->data;
  16033. + for (i = 0; i < firmware->size; i++) {
  16034. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16035. + VSC73XX_ICPU_SRAM, *dp++);
  16036. + if (rc) {
  16037. + dev_err(&spi->dev, "could not load microcode, err=%d\n",
  16038. + rc);
  16039. + goto out;
  16040. + }
  16041. + }
  16042. +
  16043. + rc = vsc7385_icpu_reset(vsc);
  16044. + if (rc)
  16045. + goto out;
  16046. +
  16047. + dev_info(&spi->dev, "verifying microcode...\n");
  16048. +
  16049. + dp = (unsigned char *) firmware->data;
  16050. + diffs = 0;
  16051. + for (i = 0; i < firmware->size; i++) {
  16052. + rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16053. + VSC73XX_ICPU_SRAM, &curVal);
  16054. + if (rc) {
  16055. + dev_err(&spi->dev, "could not read microcode %d\n",rc);
  16056. + goto out;
  16057. + }
  16058. +
  16059. + if (curVal > 0xff) {
  16060. + dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n",
  16061. + i, *dp, curVal);
  16062. + rc = -EIO;
  16063. + goto out;
  16064. + }
  16065. +
  16066. + if ((curVal & 0xff) != *dp) {
  16067. + diffs++;
  16068. + dev_err(&spi->dev, "verify error: %04x : %02x %02x\n",
  16069. + i, *dp, curVal);
  16070. +
  16071. + if (diffs > 4)
  16072. + break;
  16073. + }
  16074. + dp++;
  16075. + }
  16076. +
  16077. + if (diffs) {
  16078. + dev_err(&spi->dev, "microcode verification failed\n");
  16079. + rc = -EIO;
  16080. + goto out;
  16081. + }
  16082. +
  16083. + dev_info(&spi->dev, "microcode uploaded\n");
  16084. +
  16085. + rc = vsc7385_icpu_start(vsc);
  16086. +
  16087. + out:
  16088. + release_firmware(firmware);
  16089. + return rc;
  16090. +}
  16091. +
  16092. +static int vsc7385_setup(struct vsc7385 *vsc)
  16093. +{
  16094. + struct vsc7385_platform_data *pdata = vsc->pdata;
  16095. + u32 t;
  16096. + int err;
  16097. +
  16098. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16099. + VSC73XX_ICPU_CLOCK_DELAY,
  16100. + VSC7385_CLOCK_DELAY,
  16101. + VSC7385_CLOCK_DELAY_MASK,
  16102. + VSC7385_CLOCK_DELAY);
  16103. + if (err)
  16104. + goto err;
  16105. +
  16106. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC,
  16107. + VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM,
  16108. + VSC7385_ADVPORTM_INIT,
  16109. + VSC7385_ADVPORTM_MASK,
  16110. + VSC7385_ADVPORTM_INIT);
  16111. + if (err)
  16112. + goto err;
  16113. +
  16114. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16115. + VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET);
  16116. + if (err)
  16117. + goto err;
  16118. +
  16119. + t = VSC73XX_MAC_CFG_INIT;
  16120. + t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg);
  16121. + t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel);
  16122. + if (pdata->mac_cfg.bit2)
  16123. + t |= VSC73XX_MAC_CFG_BIT2;
  16124. +
  16125. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16126. + VSC73XX_MAC_CFG, t);
  16127. + if (err)
  16128. + goto err;
  16129. +
  16130. + return 0;
  16131. +
  16132. + err:
  16133. + return err;
  16134. +}
  16135. +
  16136. +static int vsc7385_detect(struct vsc7385 *vsc)
  16137. +{
  16138. + struct spi_device *spi = vsc->spi;
  16139. + u32 t;
  16140. + u32 id;
  16141. + u32 rev;
  16142. + int err;
  16143. +
  16144. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16145. + VSC73XX_ICPU_MBOX_VAL, &t);
  16146. + if (err) {
  16147. + dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err);
  16148. + return err;
  16149. + }
  16150. +
  16151. + if (t == 0xffffffff) {
  16152. + dev_dbg(&spi->dev, "assert chip reset\n");
  16153. + if (vsc->pdata->reset)
  16154. + vsc->pdata->reset();
  16155. +
  16156. + }
  16157. +
  16158. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16159. + VSC73XX_ICPU_CHIPID, &t);
  16160. + if (err) {
  16161. + dev_err(&spi->dev, "unable to read chip id, err=%d\n", err);
  16162. + return err;
  16163. + }
  16164. +
  16165. + id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK;
  16166. + switch (id) {
  16167. + case VSC73XX_ICPU_CHIPID_ID_7385:
  16168. + case VSC73XX_ICPU_CHIPID_ID_7395:
  16169. + break;
  16170. + default:
  16171. + dev_err(&spi->dev, "unsupported chip, id=%04x\n", id);
  16172. + return -ENODEV;
  16173. + }
  16174. +
  16175. + rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) &
  16176. + VSC73XX_ICPU_CHIPID_REV_MASK;
  16177. + dev_info(&spi->dev, "VSC%04X (rev. %d) switch found \n", id, rev);
  16178. +
  16179. + return 0;
  16180. +}
  16181. +
  16182. +static int __devinit vsc7385_probe(struct spi_device *spi)
  16183. +{
  16184. + struct vsc7385 *vsc;
  16185. + struct vsc7385_platform_data *pdata;
  16186. + int err;
  16187. +
  16188. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
  16189. +
  16190. + pdata = spi->dev.platform_data;
  16191. + if (!pdata) {
  16192. + dev_err(&spi->dev, "no platform data specified\n");
  16193. + return-ENODEV;
  16194. + }
  16195. +
  16196. + vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
  16197. + if (!vsc) {
  16198. + dev_err(&spi->dev, "no memory for private data\n");
  16199. + return-ENOMEM;
  16200. + }
  16201. +
  16202. + mutex_init(&vsc->lock);
  16203. + vsc->pdata = pdata;
  16204. + vsc->spi = spi_dev_get(spi);
  16205. + dev_set_drvdata(&spi->dev, vsc);
  16206. +
  16207. + spi->mode = SPI_MODE_0;
  16208. + spi->bits_per_word = 8;
  16209. + err = spi_setup(spi);
  16210. + if (err) {
  16211. + dev_err(&spi->dev, "spi_setup failed, err=%d \n", err);
  16212. + goto err_drvdata;
  16213. + }
  16214. +
  16215. + err = vsc7385_detect(vsc);
  16216. + if (err) {
  16217. + dev_err(&spi->dev, "no chip found, err=%d \n", err);
  16218. + goto err_drvdata;
  16219. + }
  16220. +
  16221. + err = vsc7385_upload_ucode(vsc);
  16222. + if (err)
  16223. + goto err_drvdata;
  16224. +
  16225. + err = vsc7385_setup(vsc);
  16226. + if (err)
  16227. + goto err_drvdata;
  16228. +
  16229. + return 0;
  16230. +
  16231. + err_drvdata:
  16232. + dev_set_drvdata(&spi->dev, NULL);
  16233. + kfree(vsc);
  16234. + return err;
  16235. +}
  16236. +
  16237. +static int __devexit vsc7385_remove(struct spi_device *spi)
  16238. +{
  16239. + struct vsc7385_data *vsc;
  16240. +
  16241. + vsc = dev_get_drvdata(&spi->dev);
  16242. + dev_set_drvdata(&spi->dev, NULL);
  16243. + kfree(vsc);
  16244. +
  16245. + return 0;
  16246. +}
  16247. +
  16248. +static struct spi_driver vsc7385_driver = {
  16249. + .driver = {
  16250. + .name = DRV_NAME,
  16251. + .bus = &spi_bus_type,
  16252. + .owner = THIS_MODULE,
  16253. + },
  16254. + .probe = vsc7385_probe,
  16255. + .remove = __devexit_p(vsc7385_remove),
  16256. +};
  16257. +
  16258. +static int __init vsc7385_init(void)
  16259. +{
  16260. + return spi_register_driver(&vsc7385_driver);
  16261. +}
  16262. +module_init(vsc7385_init);
  16263. +
  16264. +static void __exit vsc7385_exit(void)
  16265. +{
  16266. + spi_unregister_driver(&vsc7385_driver);
  16267. +}
  16268. +module_exit(vsc7385_exit);
  16269. +
  16270. +MODULE_DESCRIPTION(DRV_DESC);
  16271. +MODULE_VERSION(DRV_VERSION);
  16272. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  16273. +MODULE_LICENSE("GPL v2");
  16274. +
  16275. diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig
  16276. --- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200
  16277. +++ linux-2.6.39/drivers/usb/host/Kconfig 2011-05-27 14:36:51.000000000 +0200
  16278. @@ -129,6 +129,13 @@
  16279. config USB_FSL_MPH_DR_OF
  16280. tristate
  16281. +config USB_EHCI_AR71XX
  16282. + bool "USB EHCI support for AR71xx"
  16283. + depends on USB_EHCI_HCD && ATHEROS_AR71XX
  16284. + default y
  16285. + help
  16286. + Support for Atheros AR71xx built-in EHCI controller
  16287. +
  16288. config USB_EHCI_FSL
  16289. bool "Support for Freescale on-chip EHCI USB controller"
  16290. depends on USB_EHCI_HCD && FSL_SOC
  16291. @@ -287,6 +294,13 @@
  16292. Enables support for the on-chip OHCI controller on
  16293. OMAP3 and later chips.
  16294. +config USB_OHCI_AR71XX
  16295. + bool "USB OHCI support for Atheros AR71xx"
  16296. + depends on USB_OHCI_HCD && ATHEROS_AR71XX
  16297. + default y
  16298. + help
  16299. + Support for Atheros AR71xx built-in OHCI controller
  16300. +
  16301. config USB_OHCI_HCD_PPC_SOC
  16302. bool "OHCI support for on-chip PPC USB controller"
  16303. depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
  16304. diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/usb/host/ehci-ar71xx.c
  16305. --- linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16306. +++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-05-27 14:36:51.000000000 +0200
  16307. @@ -0,0 +1,242 @@
  16308. +/*
  16309. + * Bus Glue for Atheros AR71xx built-in EHCI controller.
  16310. + *
  16311. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  16312. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16313. + *
  16314. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16315. + * Copyright (C) 2007 Atheros Communications, Inc.
  16316. + *
  16317. + * This program is free software; you can redistribute it and/or modify it
  16318. + * under the terms of the GNU General Public License version 2 as published
  16319. + * by the Free Software Foundation.
  16320. + */
  16321. +
  16322. +#include <linux/platform_device.h>
  16323. +#include <linux/delay.h>
  16324. +
  16325. +#include <asm/mach-ar71xx/platform.h>
  16326. +
  16327. +extern int usb_disabled(void);
  16328. +
  16329. +static int ehci_ar71xx_init(struct usb_hcd *hcd)
  16330. +{
  16331. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16332. + int ret;
  16333. +
  16334. + ehci->caps = hcd->regs;
  16335. + ehci->regs = hcd->regs +
  16336. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16337. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16338. +
  16339. + ehci->sbrn = 0x20;
  16340. + ehci->has_synopsys_hc_bug = 1;
  16341. +
  16342. + ehci_reset(ehci);
  16343. +
  16344. + ret = ehci_init(hcd);
  16345. + if (ret)
  16346. + return ret;
  16347. +
  16348. + ehci_port_power(ehci, 0);
  16349. +
  16350. + return 0;
  16351. +}
  16352. +
  16353. +static int ehci_ar91xx_init(struct usb_hcd *hcd)
  16354. +{
  16355. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16356. + int ret;
  16357. +
  16358. + ehci->caps = hcd->regs + 0x100;
  16359. + ehci->regs = hcd->regs + 0x100 +
  16360. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16361. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16362. +
  16363. + hcd->has_tt = 1;
  16364. + ehci->sbrn = 0x20;
  16365. +
  16366. + ehci_reset(ehci);
  16367. +
  16368. + ret = ehci_init(hcd);
  16369. + if (ret)
  16370. + return ret;
  16371. +
  16372. + ehci_port_power(ehci, 0);
  16373. +
  16374. + return 0;
  16375. +}
  16376. +
  16377. +static int ehci_ar71xx_probe(const struct hc_driver *driver,
  16378. + struct usb_hcd **hcd_out,
  16379. + struct platform_device *pdev)
  16380. +{
  16381. + struct usb_hcd *hcd;
  16382. + struct resource *res;
  16383. + int irq;
  16384. + int ret;
  16385. +
  16386. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16387. + if (!res) {
  16388. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16389. + dev_name(&pdev->dev));
  16390. + return -ENODEV;
  16391. + }
  16392. + irq = res->start;
  16393. +
  16394. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16395. + if (!res) {
  16396. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16397. + dev_name(&pdev->dev));
  16398. + return -ENODEV;
  16399. + }
  16400. +
  16401. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16402. + if (!hcd)
  16403. + return -ENOMEM;
  16404. +
  16405. + hcd->rsrc_start = res->start;
  16406. + hcd->rsrc_len = res->end - res->start + 1;
  16407. +
  16408. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16409. + dev_dbg(&pdev->dev, "controller already in use\n");
  16410. + ret = -EBUSY;
  16411. + goto err_put_hcd;
  16412. + }
  16413. +
  16414. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16415. + if (!hcd->regs) {
  16416. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16417. + ret = -EFAULT;
  16418. + goto err_release_region;
  16419. + }
  16420. +
  16421. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  16422. + if (ret)
  16423. + goto err_iounmap;
  16424. +
  16425. + return 0;
  16426. +
  16427. + err_iounmap:
  16428. + iounmap(hcd->regs);
  16429. +
  16430. + err_release_region:
  16431. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16432. + err_put_hcd:
  16433. + usb_put_hcd(hcd);
  16434. + return ret;
  16435. +}
  16436. +
  16437. +static void ehci_ar71xx_remove(struct usb_hcd *hcd,
  16438. + struct platform_device *pdev)
  16439. +{
  16440. + usb_remove_hcd(hcd);
  16441. + iounmap(hcd->regs);
  16442. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16443. + usb_put_hcd(hcd);
  16444. +}
  16445. +
  16446. +static const struct hc_driver ehci_ar71xx_hc_driver = {
  16447. + .description = hcd_name,
  16448. + .product_desc = "Atheros AR71xx built-in EHCI controller",
  16449. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16450. +
  16451. + .irq = ehci_irq,
  16452. + .flags = HCD_MEMORY | HCD_USB2,
  16453. +
  16454. + .reset = ehci_ar71xx_init,
  16455. + .start = ehci_run,
  16456. + .stop = ehci_stop,
  16457. + .shutdown = ehci_shutdown,
  16458. +
  16459. + .urb_enqueue = ehci_urb_enqueue,
  16460. + .urb_dequeue = ehci_urb_dequeue,
  16461. + .endpoint_disable = ehci_endpoint_disable,
  16462. + .endpoint_reset = ehci_endpoint_reset,
  16463. +
  16464. + .get_frame_number = ehci_get_frame,
  16465. +
  16466. + .hub_status_data = ehci_hub_status_data,
  16467. + .hub_control = ehci_hub_control,
  16468. +#ifdef CONFIG_PM
  16469. + .hub_suspend = ehci_hub_suspend,
  16470. + .hub_resume = ehci_hub_resume,
  16471. +#endif
  16472. + .relinquish_port = ehci_relinquish_port,
  16473. + .port_handed_over = ehci_port_handed_over,
  16474. +
  16475. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16476. +};
  16477. +
  16478. +static const struct hc_driver ehci_ar91xx_hc_driver = {
  16479. + .description = hcd_name,
  16480. + .product_desc = "Atheros AR91xx built-in EHCI controller",
  16481. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16482. + .irq = ehci_irq,
  16483. + .flags = HCD_MEMORY | HCD_USB2,
  16484. +
  16485. + .reset = ehci_ar91xx_init,
  16486. + .start = ehci_run,
  16487. + .stop = ehci_stop,
  16488. + .shutdown = ehci_shutdown,
  16489. +
  16490. + .urb_enqueue = ehci_urb_enqueue,
  16491. + .urb_dequeue = ehci_urb_dequeue,
  16492. + .endpoint_disable = ehci_endpoint_disable,
  16493. + .endpoint_reset = ehci_endpoint_reset,
  16494. +
  16495. + .get_frame_number = ehci_get_frame,
  16496. +
  16497. + .hub_status_data = ehci_hub_status_data,
  16498. + .hub_control = ehci_hub_control,
  16499. +#ifdef CONFIG_PM
  16500. + .hub_suspend = ehci_hub_suspend,
  16501. + .hub_resume = ehci_hub_resume,
  16502. +#endif
  16503. + .relinquish_port = ehci_relinquish_port,
  16504. + .port_handed_over = ehci_port_handed_over,
  16505. +
  16506. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16507. +};
  16508. +
  16509. +static int ehci_ar71xx_driver_probe(struct platform_device *pdev)
  16510. +{
  16511. + struct ar71xx_ehci_platform_data *pdata;
  16512. + struct usb_hcd *hcd = NULL;
  16513. + int ret;
  16514. +
  16515. + if (usb_disabled())
  16516. + return -ENODEV;
  16517. +
  16518. + pdata = pdev->dev.platform_data;
  16519. + if (!pdata) {
  16520. + dev_err(&pdev->dev, "no platform data specified for %s\n",
  16521. + dev_name(&pdev->dev));
  16522. + return -ENODEV;
  16523. + }
  16524. +
  16525. + if (pdata->is_ar91xx)
  16526. + ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev);
  16527. + else
  16528. + ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev);
  16529. +
  16530. + return ret;
  16531. +}
  16532. +
  16533. +static int ehci_ar71xx_driver_remove(struct platform_device *pdev)
  16534. +{
  16535. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16536. +
  16537. + ehci_ar71xx_remove(hcd, pdev);
  16538. + return 0;
  16539. +}
  16540. +
  16541. +MODULE_ALIAS("platform:ar71xx-ehci");
  16542. +
  16543. +static struct platform_driver ehci_ar71xx_driver = {
  16544. + .probe = ehci_ar71xx_driver_probe,
  16545. + .remove = ehci_ar71xx_driver_remove,
  16546. + .driver = {
  16547. + .name = "ar71xx-ehci",
  16548. + }
  16549. +};
  16550. diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb/host/ehci-hcd.c
  16551. --- linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c 2011-05-19 06:06:34.000000000 +0200
  16552. +++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-05-27 14:36:51.000000000 +0200
  16553. @@ -1265,6 +1265,11 @@
  16554. #define PLATFORM_DRIVER tegra_ehci_driver
  16555. #endif
  16556. +#ifdef CONFIG_USB_EHCI_AR71XX
  16557. +#include "ehci-ar71xx.c"
  16558. +#define PLATFORM_DRIVER ehci_ar71xx_driver
  16559. +#endif
  16560. +
  16561. #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
  16562. !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
  16563. !defined(XILINX_OF_PLATFORM_DRIVER)
  16564. diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/usb/host/ohci-ar71xx.c
  16565. --- linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16566. +++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-05-27 14:36:51.000000000 +0200
  16567. @@ -0,0 +1,165 @@
  16568. +/*
  16569. + * OHCI HCD (Host Controller Driver) for USB.
  16570. + *
  16571. + * Bus Glue for Atheros AR71xx built-in OHCI controller.
  16572. + *
  16573. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  16574. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16575. + *
  16576. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16577. + * Copyright (C) 2007 Atheros Communications, Inc.
  16578. + *
  16579. + * This program is free software; you can redistribute it and/or modify it
  16580. + * under the terms of the GNU General Public License version 2 as published
  16581. + * by the Free Software Foundation.
  16582. + */
  16583. +
  16584. +#include <linux/platform_device.h>
  16585. +#include <linux/delay.h>
  16586. +
  16587. +extern int usb_disabled(void);
  16588. +
  16589. +static int usb_hcd_ar71xx_probe(const struct hc_driver *driver,
  16590. + struct platform_device *pdev)
  16591. +{
  16592. + struct usb_hcd *hcd;
  16593. + struct resource *res;
  16594. + int irq;
  16595. + int ret;
  16596. +
  16597. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16598. + if (!res) {
  16599. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16600. + dev_name(&pdev->dev));
  16601. + return -ENODEV;
  16602. + }
  16603. + irq = res->start;
  16604. +
  16605. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16606. + if (!hcd)
  16607. + return -ENOMEM;
  16608. +
  16609. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16610. + if (!res) {
  16611. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16612. + dev_name(&pdev->dev));
  16613. + ret = -ENODEV;
  16614. + goto err_put_hcd;
  16615. + }
  16616. + hcd->rsrc_start = res->start;
  16617. + hcd->rsrc_len = res->end - res->start + 1;
  16618. +
  16619. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16620. + dev_dbg(&pdev->dev, "controller already in use\n");
  16621. + ret = -EBUSY;
  16622. + goto err_put_hcd;
  16623. + }
  16624. +
  16625. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16626. + if (!hcd->regs) {
  16627. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16628. + ret = -EFAULT;
  16629. + goto err_release_region;
  16630. + }
  16631. +
  16632. + ohci_hcd_init(hcd_to_ohci(hcd));
  16633. +
  16634. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  16635. + if (ret)
  16636. + goto err_stop_hcd;
  16637. +
  16638. + return 0;
  16639. +
  16640. + err_stop_hcd:
  16641. + iounmap(hcd->regs);
  16642. + err_release_region:
  16643. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16644. + err_put_hcd:
  16645. + usb_put_hcd(hcd);
  16646. + return ret;
  16647. +}
  16648. +
  16649. +void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  16650. +{
  16651. + usb_remove_hcd(hcd);
  16652. + iounmap(hcd->regs);
  16653. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16654. + usb_put_hcd(hcd);
  16655. +}
  16656. +
  16657. +static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd)
  16658. +{
  16659. + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  16660. + int ret;
  16661. +
  16662. + ret = ohci_init(ohci);
  16663. + if (ret < 0)
  16664. + return ret;
  16665. +
  16666. + ret = ohci_run(ohci);
  16667. + if (ret < 0)
  16668. + goto err;
  16669. +
  16670. + return 0;
  16671. +
  16672. + err:
  16673. + ohci_stop(hcd);
  16674. + return ret;
  16675. +}
  16676. +
  16677. +static const struct hc_driver ohci_ar71xx_hc_driver = {
  16678. + .description = hcd_name,
  16679. + .product_desc = "Atheros AR71xx built-in OHCI controller",
  16680. + .hcd_priv_size = sizeof(struct ohci_hcd),
  16681. +
  16682. + .irq = ohci_irq,
  16683. + .flags = HCD_USB11 | HCD_MEMORY,
  16684. +
  16685. + .start = ohci_ar71xx_start,
  16686. + .stop = ohci_stop,
  16687. + .shutdown = ohci_shutdown,
  16688. +
  16689. + .urb_enqueue = ohci_urb_enqueue,
  16690. + .urb_dequeue = ohci_urb_dequeue,
  16691. + .endpoint_disable = ohci_endpoint_disable,
  16692. +
  16693. + /*
  16694. + * scheduling support
  16695. + */
  16696. + .get_frame_number = ohci_get_frame,
  16697. +
  16698. + /*
  16699. + * root hub support
  16700. + */
  16701. + .hub_status_data = ohci_hub_status_data,
  16702. + .hub_control = ohci_hub_control,
  16703. + .start_port_reset = ohci_start_port_reset,
  16704. +};
  16705. +
  16706. +static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev)
  16707. +{
  16708. + if (usb_disabled())
  16709. + return -ENODEV;
  16710. +
  16711. + return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev);
  16712. +}
  16713. +
  16714. +static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev)
  16715. +{
  16716. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16717. +
  16718. + usb_hcd_ar71xx_remove(hcd, pdev);
  16719. + return 0;
  16720. +}
  16721. +
  16722. +MODULE_ALIAS("platform:ar71xx-ohci");
  16723. +
  16724. +static struct platform_driver ohci_hcd_ar71xx_driver = {
  16725. + .probe = ohci_hcd_ar71xx_drv_probe,
  16726. + .remove = ohci_hcd_ar71xx_drv_remove,
  16727. + .shutdown = usb_hcd_platform_shutdown,
  16728. + .driver = {
  16729. + .name = "ar71xx-ohci",
  16730. + .owner = THIS_MODULE,
  16731. + },
  16732. +};
  16733. diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb/host/ohci-hcd.c
  16734. --- linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c 2011-05-19 06:06:34.000000000 +0200
  16735. +++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-05-27 14:36:51.000000000 +0200
  16736. @@ -1105,6 +1105,11 @@
  16737. #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
  16738. #endif
  16739. +#ifdef CONFIG_USB_OHCI_AR71XX
  16740. +#include "ohci-ar71xx.c"
  16741. +#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
  16742. +#endif
  16743. +
  16744. #if !defined(PCI_DRIVER) && \
  16745. !defined(PLATFORM_DRIVER) && \
  16746. !defined(OMAP1_PLATFORM_DRIVER) && \
  16747. diff -Nur linux-2.6.39.orig/drivers/watchdog/Kconfig linux-2.6.39/drivers/watchdog/Kconfig
  16748. --- linux-2.6.39.orig/drivers/watchdog/Kconfig 2011-05-19 06:06:34.000000000 +0200
  16749. +++ linux-2.6.39/drivers/watchdog/Kconfig 2011-05-27 14:36:51.000000000 +0200
  16750. @@ -990,6 +990,13 @@
  16751. To compile this driver as a loadable module, choose M here.
  16752. The module will be called bcm63xx_wdt.
  16753. +config AR71XX_WDT
  16754. + tristate "Atheros AR71xx Watchdog Timer"
  16755. + depends on ATHEROS_AR71XX
  16756. + help
  16757. + Hardware driver for the built-in watchdog timer on the Atheros
  16758. + AR71xx SoCs.
  16759. +
  16760. # PARISC Architecture
  16761. # POWERPC Architecture
  16762. diff -Nur linux-2.6.39.orig/drivers/watchdog/Makefile linux-2.6.39/drivers/watchdog/Makefile
  16763. --- linux-2.6.39.orig/drivers/watchdog/Makefile 2011-05-19 06:06:34.000000000 +0200
  16764. +++ linux-2.6.39/drivers/watchdog/Makefile 2011-05-27 14:36:51.000000000 +0200
  16765. @@ -121,6 +121,7 @@
  16766. obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
  16767. obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
  16768. obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
  16769. +obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
  16770. obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
  16771. octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
  16772. diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/watchdog/ar71xx_wdt.c
  16773. --- linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100
  16774. +++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-05-27 14:36:51.000000000 +0200
  16775. @@ -0,0 +1,270 @@
  16776. +/*
  16777. + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer.
  16778. + *
  16779. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  16780. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16781. + *
  16782. + * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
  16783. + * Author: Deepak Saxena <dsaxena@plexity.net>
  16784. + * Copyright 2004 (c) MontaVista, Software, Inc.
  16785. + *
  16786. + * which again was based on sa1100 driver,
  16787. + * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
  16788. + *
  16789. + * This program is free software; you can redistribute it and/or modify it
  16790. + * under the terms of the GNU General Public License version 2 as published
  16791. + * by the Free Software Foundation.
  16792. + *
  16793. + */
  16794. +
  16795. +#include <linux/bitops.h>
  16796. +#include <linux/errno.h>
  16797. +#include <linux/fs.h>
  16798. +#include <linux/init.h>
  16799. +#include <linux/kernel.h>
  16800. +#include <linux/miscdevice.h>
  16801. +#include <linux/module.h>
  16802. +#include <linux/moduleparam.h>
  16803. +#include <linux/platform_device.h>
  16804. +#include <linux/types.h>
  16805. +#include <linux/watchdog.h>
  16806. +
  16807. +#include <asm/mach-ar71xx/ar71xx.h>
  16808. +
  16809. +#define DRV_NAME "ar71xx-wdt"
  16810. +#define DRV_DESC "Atheros AR71xx hardware watchdog driver"
  16811. +#define DRV_VERSION "0.1.0"
  16812. +
  16813. +#define WDT_TIMEOUT 15 /* seconds */
  16814. +
  16815. +static int nowayout = WATCHDOG_NOWAYOUT;
  16816. +
  16817. +#ifdef CONFIG_WATCHDOG_NOWAYOUT
  16818. +module_param(nowayout, int, 0);
  16819. +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  16820. + "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  16821. +#endif
  16822. +
  16823. +static unsigned long wdt_flags;
  16824. +
  16825. +#define WDT_FLAGS_BUSY 0
  16826. +#define WDT_FLAGS_EXPECT_CLOSE 1
  16827. +
  16828. +static int wdt_timeout = WDT_TIMEOUT;
  16829. +static int boot_status;
  16830. +static int max_timeout;
  16831. +
  16832. +static void inline ar71xx_wdt_keepalive(void)
  16833. +{
  16834. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout);
  16835. +}
  16836. +
  16837. +static void inline ar71xx_wdt_enable(void)
  16838. +{
  16839. + printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n");
  16840. + ar71xx_wdt_keepalive();
  16841. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
  16842. +}
  16843. +
  16844. +static void inline ar71xx_wdt_disable(void)
  16845. +{
  16846. + printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n");
  16847. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
  16848. +}
  16849. +
  16850. +static int ar71xx_wdt_set_timeout(int val)
  16851. +{
  16852. + if (val < 1 || val > max_timeout)
  16853. + return -EINVAL;
  16854. +
  16855. + wdt_timeout = val;
  16856. + ar71xx_wdt_keepalive();
  16857. +
  16858. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout);
  16859. +
  16860. + return 0;
  16861. +}
  16862. +
  16863. +static int ar71xx_wdt_open(struct inode *inode, struct file *file)
  16864. +{
  16865. + if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
  16866. + return -EBUSY;
  16867. +
  16868. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  16869. +
  16870. + ar71xx_wdt_enable();
  16871. +
  16872. + return nonseekable_open(inode, file);
  16873. +}
  16874. +
  16875. +static int ar71xx_wdt_release(struct inode *inode, struct file *file)
  16876. +{
  16877. + if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) {
  16878. + ar71xx_wdt_disable();
  16879. + } else {
  16880. + printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, "
  16881. + "watchdog timer will not stop!\n");
  16882. + }
  16883. +
  16884. + clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
  16885. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  16886. +
  16887. + return 0;
  16888. +}
  16889. +
  16890. +static ssize_t ar71xx_wdt_write(struct file *file, const char *data,
  16891. + size_t len, loff_t *ppos)
  16892. +{
  16893. + if (len) {
  16894. + if (!nowayout) {
  16895. + size_t i;
  16896. +
  16897. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  16898. +
  16899. + for (i = 0; i != len; i++) {
  16900. + char c;
  16901. +
  16902. + if (get_user(c, data + i))
  16903. + return -EFAULT;
  16904. +
  16905. + if (c == 'V')
  16906. + set_bit(WDT_FLAGS_EXPECT_CLOSE,
  16907. + &wdt_flags);
  16908. + }
  16909. + }
  16910. +
  16911. + ar71xx_wdt_keepalive();
  16912. + }
  16913. +
  16914. + return len;
  16915. +}
  16916. +
  16917. +static struct watchdog_info ar71xx_wdt_info = {
  16918. + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
  16919. + WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
  16920. + .firmware_version = 0,
  16921. + .identity = "AR71XX watchdog",
  16922. +};
  16923. +
  16924. +static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file,
  16925. + unsigned int cmd, unsigned long arg)
  16926. +{
  16927. + int t;
  16928. + int ret;
  16929. +
  16930. + switch (cmd) {
  16931. + case WDIOC_GETSUPPORT:
  16932. + ret = copy_to_user((struct watchdog_info *)arg,
  16933. + &ar71xx_wdt_info,
  16934. + sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0;
  16935. + break;
  16936. +
  16937. + case WDIOC_GETSTATUS:
  16938. + ret = put_user(0, (int *)arg) ? -EFAULT : 0;
  16939. + break;
  16940. +
  16941. + case WDIOC_GETBOOTSTATUS:
  16942. + ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0;
  16943. + break;
  16944. +
  16945. + case WDIOC_KEEPALIVE:
  16946. + ar71xx_wdt_keepalive();
  16947. + ret = 0;
  16948. + break;
  16949. +
  16950. + case WDIOC_SETTIMEOUT:
  16951. + ret = get_user(t, (int *)arg) ? -EFAULT : 0;
  16952. + if (ret)
  16953. + break;
  16954. +
  16955. + ret = ar71xx_wdt_set_timeout(t);
  16956. + if (ret)
  16957. + break;
  16958. +
  16959. + /* fallthrough */
  16960. + case WDIOC_GETTIMEOUT:
  16961. + ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0;
  16962. + break;
  16963. +
  16964. + default:
  16965. + ret = -ENOTTY;
  16966. + break;
  16967. + }
  16968. +
  16969. + return ret;
  16970. +}
  16971. +
  16972. +static const struct file_operations ar71xx_wdt_fops = {
  16973. + .owner = THIS_MODULE,
  16974. + .write = ar71xx_wdt_write,
  16975. + .ioctl = ar71xx_wdt_ioctl,
  16976. + .open = ar71xx_wdt_open,
  16977. + .release = ar71xx_wdt_release,
  16978. +};
  16979. +
  16980. +static struct miscdevice ar71xx_wdt_miscdev = {
  16981. + .minor = WATCHDOG_MINOR,
  16982. + .name = "watchdog",
  16983. + .fops = &ar71xx_wdt_fops,
  16984. +};
  16985. +
  16986. +static int __devinit ar71xx_wdt_probe(struct platform_device *pdev)
  16987. +{
  16988. + int ret;
  16989. +
  16990. + max_timeout = (0xfffffffful / ar71xx_ahb_freq);
  16991. + wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
  16992. +
  16993. + boot_status =
  16994. + (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ?
  16995. + WDIOF_CARDRESET : 0;
  16996. +
  16997. + ret = misc_register(&ar71xx_wdt_miscdev);
  16998. + if (ret)
  16999. + goto err_out;
  17000. +
  17001. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  17002. +
  17003. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n",
  17004. + wdt_timeout, max_timeout);
  17005. +
  17006. + return 0;
  17007. +
  17008. +err_out:
  17009. + return ret;
  17010. +}
  17011. +
  17012. +static int __devexit ar71xx_wdt_remove(struct platform_device *pdev)
  17013. +{
  17014. + misc_deregister(&ar71xx_wdt_miscdev);
  17015. + return 0;
  17016. +}
  17017. +
  17018. +static struct platform_driver ar71xx_wdt_driver = {
  17019. + .probe = ar71xx_wdt_probe,
  17020. + .remove = __devexit_p(ar71xx_wdt_remove),
  17021. + .driver = {
  17022. + .name = DRV_NAME,
  17023. + .owner = THIS_MODULE,
  17024. + },
  17025. +};
  17026. +
  17027. +static int __init ar71xx_wdt_init(void)
  17028. +{
  17029. + return platform_driver_register(&ar71xx_wdt_driver);
  17030. +}
  17031. +module_init(ar71xx_wdt_init);
  17032. +
  17033. +static void __exit ar71xx_wdt_exit(void)
  17034. +{
  17035. + platform_driver_unregister(&ar71xx_wdt_driver);
  17036. +}
  17037. +module_exit(ar71xx_wdt_exit);
  17038. +
  17039. +MODULE_DESCRIPTION(DRV_DESC);
  17040. +MODULE_VERSION(DRV_VERSION);
  17041. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
  17042. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
  17043. +MODULE_LICENSE("GPL v2");
  17044. +MODULE_ALIAS("platform:" DRV_NAME);
  17045. +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  17046. diff -Nur linux-2.6.39.orig/include/linux/ath9k_platform.h linux-2.6.39/include/linux/ath9k_platform.h
  17047. --- linux-2.6.39.orig/include/linux/ath9k_platform.h 2011-05-19 06:06:34.000000000 +0200
  17048. +++ linux-2.6.39/include/linux/ath9k_platform.h 2011-05-27 14:36:51.000000000 +0200
  17049. @@ -1,19 +1,11 @@
  17050. /*
  17051. - * Copyright (c) 2008 Atheros Communications Inc.
  17052. - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  17053. - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
  17054. + * ath9k platform data defines
  17055. *
  17056. - * Permission to use, copy, modify, and/or distribute this software for any
  17057. - * purpose with or without fee is hereby granted, provided that the above
  17058. - * copyright notice and this permission notice appear in all copies.
  17059. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  17060. *
  17061. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  17062. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  17063. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  17064. - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17065. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17066. - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17067. - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17068. + * This program is free software; you can redistribute it and/or modify it
  17069. + * under the terms of the GNU General Public License version 2 as published
  17070. + * by the Free Software Foundation.
  17071. */
  17072. #ifndef _LINUX_ATH9K_PLATFORM_H
  17073. @@ -23,6 +15,9 @@
  17074. struct ath9k_platform_data {
  17075. u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  17076. + u8 *macaddr;
  17077. +
  17078. + unsigned long quirk_wndr3700:1;
  17079. };
  17080. #endif /* _LINUX_ATH9K_PLATFORM_H */
  17081. diff -Nur linux-2.6.39.orig/include/linux/gpio_buttons.h linux-2.6.39/include/linux/gpio_buttons.h
  17082. --- linux-2.6.39.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100
  17083. +++ linux-2.6.39/include/linux/gpio_buttons.h 2011-05-27 14:36:51.000000000 +0200
  17084. @@ -0,0 +1,33 @@
  17085. +/*
  17086. + * Definitions for the GPIO buttons interface driver
  17087. + *
  17088. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  17089. + *
  17090. + * This file was based on: /include/linux/gpio_keys.h
  17091. + * The original gpio_keys.h seems not to have a license.
  17092. + *
  17093. + * This program is free software; you can redistribute it and/or modify
  17094. + * it under the terms of the GNU General Public License version 2 as
  17095. + * published by the Free Software Foundation.
  17096. + *
  17097. + */
  17098. +
  17099. +#ifndef _GPIO_BUTTONS_H_
  17100. +#define _GPIO_BUTTONS_H_
  17101. +
  17102. +struct gpio_button {
  17103. + int gpio; /* GPIO line number */
  17104. + int active_low;
  17105. + char *desc; /* button description */
  17106. + int type; /* input event type (EV_KEY, EV_SW) */
  17107. + int code; /* input event code (KEY_*, SW_*) */
  17108. + int threshold; /* count threshold */
  17109. +};
  17110. +
  17111. +struct gpio_buttons_platform_data {
  17112. + struct gpio_button *buttons;
  17113. + int nbuttons; /* number of buttons */
  17114. + int poll_interval; /* polling interval */
  17115. +};
  17116. +
  17117. +#endif /* _GPIO_BUTTONS_H_ */
  17118. diff -Nur linux-2.6.39.orig/include/linux/gpio_dev.h linux-2.6.39/include/linux/gpio_dev.h
  17119. --- linux-2.6.39.orig/include/linux/gpio_dev.h 1970-01-01 01:00:00.000000000 +0100
  17120. +++ linux-2.6.39/include/linux/gpio_dev.h 2011-05-27 14:36:51.000000000 +0200
  17121. @@ -0,0 +1,11 @@
  17122. +#ifndef _GPIODEV_H__
  17123. +#define _GPIODEV_H__
  17124. +
  17125. +#define IOC_GPIODEV_MAGIC 'B'
  17126. +#define GPIO_GET _IO(IOC_GPIODEV_MAGIC, 10)
  17127. +#define GPIO_SET _IO(IOC_GPIODEV_MAGIC, 11)
  17128. +#define GPIO_CLEAR _IO(IOC_GPIODEV_MAGIC, 12)
  17129. +#define GPIO_DIR_IN _IO(IOC_GPIODEV_MAGIC, 13)
  17130. +#define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 14)
  17131. +
  17132. +#endif
  17133. diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux/netdevice.h
  17134. --- linux-2.6.39.orig/include/linux/netdevice.h 2011-05-19 06:06:34.000000000 +0200
  17135. +++ linux-2.6.39/include/linux/netdevice.h 2011-05-27 14:36:51.000000000 +0200
  17136. @@ -1182,6 +1182,7 @@
  17137. void *ax25_ptr; /* AX.25 specific data */
  17138. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  17139. assign before registering */
  17140. + void *phy_ptr; /* PHY device specific data */
  17141. /*
  17142. * Cache lines mostly used on receive path (including eth_type_trans())
  17143. diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/linux/nxp_74hc153.h
  17144. --- linux-2.6.39.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100
  17145. +++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-05-27 14:36:51.000000000 +0200
  17146. @@ -0,0 +1,24 @@
  17147. +/*
  17148. + * NXP 74HC153 - Dual 4-input multiplexer defines
  17149. + *
  17150. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  17151. + *
  17152. + * This program is free software; you can redistribute it and/or modify
  17153. + * it under the terms of the GNU General Public License version 2 as
  17154. + * published by the Free Software Foundation.
  17155. + */
  17156. +
  17157. +#ifndef _NXP_74HC153_H
  17158. +#define _NXP_74HC153_H
  17159. +
  17160. +#define NXP_74HC153_DRIVER_NAME "nxp-74hc153"
  17161. +
  17162. +struct nxp_74hc153_platform_data {
  17163. + unsigned gpio_base;
  17164. + unsigned gpio_pin_s0;
  17165. + unsigned gpio_pin_s1;
  17166. + unsigned gpio_pin_1y;
  17167. + unsigned gpio_pin_2y;
  17168. +};
  17169. +
  17170. +#endif /* _NXP_74HC153_H */
  17171. diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h
  17172. --- linux-2.6.39.orig/include/linux/phy.h 2011-05-19 06:06:34.000000000 +0200
  17173. +++ linux-2.6.39/include/linux/phy.h 2011-05-27 14:36:51.000000000 +0200
  17174. @@ -332,6 +332,20 @@
  17175. void (*adjust_link)(struct net_device *dev);
  17176. void (*adjust_state)(struct net_device *dev);
  17177. +
  17178. + /*
  17179. + * By default these point to the original functions
  17180. + * with the same name. adding them to the phy_device
  17181. + * allows the phy driver to override them for packet
  17182. + * mangling if the ethernet driver supports it
  17183. + * This is required to support some really horrible
  17184. + * switches such as the Marvell 88E6060
  17185. + */
  17186. + int (*netif_receive_skb)(struct sk_buff *skb);
  17187. + int (*netif_rx)(struct sk_buff *skb);
  17188. +
  17189. + /* alignment offset for packets */
  17190. + int pkt_align;
  17191. };
  17192. #define to_phy_device(d) container_of(d, struct phy_device, dev)
  17193. @@ -508,6 +522,7 @@
  17194. void phy_stop_machine(struct phy_device *phydev);
  17195. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17196. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17197. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  17198. int phy_mii_ioctl(struct phy_device *phydev,
  17199. struct ifreq *ifr, int cmd);
  17200. int phy_start_interrupts(struct phy_device *phydev);
  17201. diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/linux/spi/vsc7385.h
  17202. --- linux-2.6.39.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100
  17203. +++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-05-27 14:36:51.000000000 +0200
  17204. @@ -0,0 +1,19 @@
  17205. +/*
  17206. + * Platform data definition for the Vitesse VSC7385 ethernet switch driver
  17207. + *
  17208. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  17209. + *
  17210. + * This program is free software; you can redistribute it and/or modify it
  17211. + * under the terms of the GNU General Public License version 2 as published
  17212. + * by the Free Software Foundation.
  17213. + */
  17214. +
  17215. +struct vsc7385_platform_data {
  17216. + void (* reset)(void);
  17217. + char *ucode_name;
  17218. + struct {
  17219. + u32 tx_ipg:5;
  17220. + u32 bit2:1;
  17221. + u32 clk_sel:3;
  17222. + } mac_cfg;
  17223. +};
  17224. diff -Nur linux-2.6.39.orig/net/dsa/ar7240.c linux-2.6.39/net/dsa/ar7240.c
  17225. --- linux-2.6.39.orig/net/dsa/ar7240.c 1970-01-01 01:00:00.000000000 +0100
  17226. +++ linux-2.6.39/net/dsa/ar7240.c 2011-05-27 14:36:51.000000000 +0200
  17227. @@ -0,0 +1,736 @@
  17228. +/*
  17229. + * DSA driver for the built-in ethernet switch of the Atheros AR7240 SoC
  17230. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  17231. + *
  17232. + * This file was based on:
  17233. + * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
  17234. + * Copyright (c) 2008 Marvell Semiconductor
  17235. + *
  17236. + * This program is free software; you can redistribute it and/or modify it
  17237. + * under the terms of the GNU General Public License version 2 as published
  17238. + * by the Free Software Foundation.
  17239. + *
  17240. + */
  17241. +
  17242. +#include <linux/etherdevice.h>
  17243. +#include <linux/list.h>
  17244. +#include <linux/netdevice.h>
  17245. +#include <linux/phy.h>
  17246. +#include <linux/mii.h>
  17247. +#include <linux/bitops.h>
  17248. +
  17249. +#include "dsa_priv.h"
  17250. +
  17251. +#define BITM(_count) (BIT(_count) - 1)
  17252. +
  17253. +#define AR7240_REG_MASK_CTRL 0x00
  17254. +#define AR7240_MASK_CTRL_REVISION_M BITM(8)
  17255. +#define AR7240_MASK_CTRL_VERSION_M BITM(8)
  17256. +#define AR7240_MASK_CTRL_VERSION_S 8
  17257. +#define AR7240_MASK_CTRL_SOFT_RESET BIT(31)
  17258. +
  17259. +#define AR7240_REG_MAC_ADDR0 0x20
  17260. +#define AR7240_REG_MAC_ADDR1 0x24
  17261. +
  17262. +#define AR7240_REG_FLOOD_MASK 0x2c
  17263. +#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26)
  17264. +
  17265. +#define AR7240_REG_GLOBAL_CTRL 0x30
  17266. +#define AR7240_GLOBAL_CTRL_MTU_M BITM(12)
  17267. +
  17268. +#define AR7240_REG_AT_CTRL 0x5c
  17269. +#define AR7240_AT_CTRL_ARP_EN BIT(20)
  17270. +
  17271. +#define AR7240_REG_TAG_PRIORITY 0x70
  17272. +
  17273. +#define AR7240_REG_SERVICE_TAG 0x74
  17274. +#define AR7240_SERVICE_TAG_M BITM(16)
  17275. +
  17276. +#define AR7240_REG_CPU_PORT 0x78
  17277. +#define AR7240_MIRROR_PORT_S 4
  17278. +#define AR7240_CPU_PORT_EN BIT(8)
  17279. +
  17280. +#define AR7240_REG_MIB_FUNCTION0 0x80
  17281. +#define AR7240_MIB_TIMER_M BITM(16)
  17282. +#define AR7240_MIB_AT_HALF_EN BIT(16)
  17283. +#define AR7240_MIB_BUSY BIT(17)
  17284. +#define AR7240_MIB_FUNC_S 24
  17285. +#define AR7240_MIB_FUNC_NO_OP 0x0
  17286. +#define AR7240_MIB_FUNC_FLUSH 0x1
  17287. +#define AR7240_MIB_FUNC_CAPTURE 0x3
  17288. +
  17289. +#define AR7240_REG_MDIO_CTRL 0x98
  17290. +#define AR7240_MDIO_CTRL_DATA_M BITM(16)
  17291. +#define AR7240_MDIO_CTRL_REG_ADDR_S 16
  17292. +#define AR7240_MDIO_CTRL_PHY_ADDR_S 21
  17293. +#define AR7240_MDIO_CTRL_CMD_WRITE 0
  17294. +#define AR7240_MDIO_CTRL_CMD_READ BIT(27)
  17295. +#define AR7240_MDIO_CTRL_MASTER_EN BIT(30)
  17296. +#define AR7240_MDIO_CTRL_BUSY BIT(31)
  17297. +
  17298. +#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100)
  17299. +
  17300. +#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00)
  17301. +#define AR7240_PORT_STATUS_SPEED_M BITM(2)
  17302. +#define AR7240_PORT_STATUS_SPEED_10 0
  17303. +#define AR7240_PORT_STATUS_SPEED_100 1
  17304. +#define AR7240_PORT_STATUS_SPEED_1000 2
  17305. +#define AR7240_PORT_STATUS_TXMAC BIT(2)
  17306. +#define AR7240_PORT_STATUS_RXMAC BIT(3)
  17307. +#define AR7240_PORT_STATUS_TXFLOW BIT(4)
  17308. +#define AR7240_PORT_STATUS_RXFLOW BIT(5)
  17309. +#define AR7240_PORT_STATUS_DUPLEX BIT(6)
  17310. +#define AR7240_PORT_STATUS_LINK_UP BIT(8)
  17311. +#define AR7240_PORT_STATUS_LINK_AUTO BIT(9)
  17312. +#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10)
  17313. +
  17314. +#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04)
  17315. +#define AR7240_PORT_CTRL_STATE_M BITM(3)
  17316. +#define AR7240_PORT_CTRL_STATE_DISABLED 0
  17317. +#define AR7240_PORT_CTRL_STATE_BLOCK 1
  17318. +#define AR7240_PORT_CTRL_STATE_LISTEN 2
  17319. +#define AR7240_PORT_CTRL_STATE_LEARN 3
  17320. +#define AR7240_PORT_CTRL_STATE_FORWARD 4
  17321. +#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7)
  17322. +#define AR7240_PORT_CTRL_VLAN_MODE_S 8
  17323. +#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0
  17324. +#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1
  17325. +#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2
  17326. +#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3
  17327. +#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10)
  17328. +#define AR7240_PORT_CTRL_HEADER BIT(11)
  17329. +#define AR7240_PORT_CTRL_MAC_LOOP BIT(12)
  17330. +#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13)
  17331. +#define AR7240_PORT_CTRL_LEARN BIT(14)
  17332. +#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15)
  17333. +#define AR7240_PORT_CTRL_MIRROR_TX BIT(16)
  17334. +#define AR7240_PORT_CTRL_MIRROR_RX BIT(17)
  17335. +
  17336. +#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08)
  17337. +
  17338. +#define AR7240_PORT_VLAN_DEFAULT_ID_S 0
  17339. +#define AR7240_PORT_VLAN_DEST_PORTS_S 16
  17340. +
  17341. +#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100)
  17342. +
  17343. +#define AR7240_STATS_RXBROAD 0x00
  17344. +#define AR7240_STATS_RXPAUSE 0x04
  17345. +#define AR7240_STATS_RXMULTI 0x08
  17346. +#define AR7240_STATS_RXFCSERR 0x0c
  17347. +#define AR7240_STATS_RXALIGNERR 0x10
  17348. +#define AR7240_STATS_RXRUNT 0x14
  17349. +#define AR7240_STATS_RXFRAGMENT 0x18
  17350. +#define AR7240_STATS_RX64BYTE 0x1c
  17351. +#define AR7240_STATS_RX128BYTE 0x20
  17352. +#define AR7240_STATS_RX256BYTE 0x24
  17353. +#define AR7240_STATS_RX512BYTE 0x28
  17354. +#define AR7240_STATS_RX1024BYTE 0x2c
  17355. +#define AR7240_STATS_RX1518BYTE 0x30
  17356. +#define AR7240_STATS_RXMAXBYTE 0x34
  17357. +#define AR7240_STATS_RXTOOLONG 0x38
  17358. +#define AR7240_STATS_RXGOODBYTE 0x3c
  17359. +#define AR7240_STATS_RXBADBYTE 0x44
  17360. +#define AR7240_STATS_RXOVERFLOW 0x4c
  17361. +#define AR7240_STATS_FILTERED 0x50
  17362. +#define AR7240_STATS_TXBROAD 0x54
  17363. +#define AR7240_STATS_TXPAUSE 0x58
  17364. +#define AR7240_STATS_TXMULTI 0x5c
  17365. +#define AR7240_STATS_TXUNDERRUN 0x60
  17366. +#define AR7240_STATS_TX64BYTE 0x64
  17367. +#define AR7240_STATS_TX128BYTE 0x68
  17368. +#define AR7240_STATS_TX256BYTE 0x6c
  17369. +#define AR7240_STATS_TX512BYTE 0x70
  17370. +#define AR7240_STATS_TX1024BYTE 0x74
  17371. +#define AR7240_STATS_TX1518BYTE 0x78
  17372. +#define AR7240_STATS_TXMAXBYTE 0x7c
  17373. +#define AR7240_STATS_TXOVERSIZE 0x80
  17374. +#define AR7240_STATS_TXBYTE 0x84
  17375. +#define AR7240_STATS_TXCOLLISION 0x8c
  17376. +#define AR7240_STATS_TXABORTCOL 0x90
  17377. +#define AR7240_STATS_TXMULTICOL 0x94
  17378. +#define AR7240_STATS_TXSINGLECOL 0x98
  17379. +#define AR7240_STATS_TXEXCDEFER 0x9c
  17380. +#define AR7240_STATS_TXDEFER 0xa0
  17381. +#define AR7240_STATS_TXLATECOL 0xa4
  17382. +
  17383. +#define AR7240_PORT_CPU 0
  17384. +#define AR7240_NUM_PORTS 6
  17385. +#define AR7240_NUM_PHYS 5
  17386. +
  17387. +#define AR7240_PHY_ID1 0x004d
  17388. +#define AR7240_PHY_ID2 0xd041
  17389. +
  17390. +#define AR7240_PORT_MASK(_port) BIT((_port))
  17391. +#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS)
  17392. +#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port)))
  17393. +
  17394. +struct ar7240sw {
  17395. + struct mii_bus *mii_bus;
  17396. + struct mutex reg_mutex;
  17397. + struct mutex stats_mutex;
  17398. +};
  17399. +
  17400. +struct ar7240sw_hw_stat {
  17401. + char string[ETH_GSTRING_LEN];
  17402. + int sizeof_stat;
  17403. + int reg;
  17404. +};
  17405. +
  17406. +static inline struct ar7240sw *dsa_to_ar7240sw(struct dsa_switch *ds)
  17407. +{
  17408. + return (struct ar7240sw *)(ds + 1);
  17409. +}
  17410. +
  17411. +static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
  17412. +{
  17413. + as->mii_bus = mii;
  17414. + mutex_init(&as->reg_mutex);
  17415. + mutex_init(&as->stats_mutex);
  17416. +}
  17417. +
  17418. +static inline u16 mk_phy_addr(u32 reg)
  17419. +{
  17420. + return (0x17 & ((reg >> 4) | 0x10));
  17421. +}
  17422. +
  17423. +static inline u16 mk_phy_reg(u32 reg)
  17424. +{
  17425. + return ((reg << 1) & 0x1e);
  17426. +}
  17427. +
  17428. +static inline u16 mk_high_addr(u32 reg)
  17429. +{
  17430. + return ((reg >> 7) & 0x1ff);
  17431. +}
  17432. +
  17433. +static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg)
  17434. +{
  17435. + struct mii_bus *mii = as->mii_bus;
  17436. + u16 phy_addr;
  17437. + u16 phy_reg;
  17438. + u32 hi, lo;
  17439. +
  17440. + reg = (reg & 0xfffffffc) >> 2;
  17441. +
  17442. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17443. +
  17444. + phy_addr = mk_phy_addr(reg);
  17445. + phy_reg = mk_phy_reg(reg);
  17446. +
  17447. + lo = (u32) mdiobus_read(mii, phy_addr, phy_reg);
  17448. + hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1);
  17449. +
  17450. + return ((hi << 16) | lo);
  17451. +}
  17452. +
  17453. +static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val)
  17454. +{
  17455. + struct mii_bus *mii = as->mii_bus;
  17456. + u16 phy_addr;
  17457. + u16 phy_reg;
  17458. +
  17459. + reg = (reg & 0xfffffffc) >> 2;
  17460. +
  17461. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17462. +
  17463. + phy_addr = mk_phy_addr(reg);
  17464. + phy_reg = mk_phy_reg(reg);
  17465. +
  17466. + mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16));
  17467. + mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff));
  17468. +}
  17469. +
  17470. +static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr)
  17471. +{
  17472. + u32 ret;
  17473. +
  17474. + mutex_lock(&as->reg_mutex);
  17475. + ret = __ar7240sw_reg_read(as, reg_addr);
  17476. + mutex_unlock(&as->reg_mutex);
  17477. +
  17478. + return ret;
  17479. +}
  17480. +
  17481. +static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val)
  17482. +{
  17483. + mutex_lock(&as->reg_mutex);
  17484. + __ar7240sw_reg_write(as, reg_addr, reg_val);
  17485. + mutex_unlock(&as->reg_mutex);
  17486. +}
  17487. +
  17488. +static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val)
  17489. +{
  17490. + u32 t;
  17491. +
  17492. + mutex_lock(&as->reg_mutex);
  17493. + t = __ar7240sw_reg_read(as, reg);
  17494. + t &= ~mask;
  17495. + t |= val;
  17496. + __ar7240sw_reg_write(as, reg, t);
  17497. + mutex_unlock(&as->reg_mutex);
  17498. +
  17499. + return t;
  17500. +}
  17501. +
  17502. +static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val)
  17503. +{
  17504. + u32 t;
  17505. +
  17506. + mutex_lock(&as->reg_mutex);
  17507. + t = __ar7240sw_reg_read(as, reg);
  17508. + t |= val;
  17509. + __ar7240sw_reg_write(as, reg, t);
  17510. + mutex_unlock(&as->reg_mutex);
  17511. +}
  17512. +
  17513. +static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
  17514. + unsigned timeout)
  17515. +{
  17516. + int i;
  17517. +
  17518. + for (i = 0; i < timeout; i++) {
  17519. + u32 t;
  17520. +
  17521. + t = ar7240sw_reg_read(as, reg);
  17522. + if ((t & mask) == val)
  17523. + return 0;
  17524. +
  17525. + msleep(1);
  17526. + }
  17527. +
  17528. + return -ETIMEDOUT;
  17529. +}
  17530. +
  17531. +static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr,
  17532. + unsigned reg_addr)
  17533. +{
  17534. + u32 t;
  17535. + int err;
  17536. +
  17537. + if (phy_addr >= AR7240_NUM_PHYS)
  17538. + return 0xffff;
  17539. +
  17540. + t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17541. + (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17542. + AR7240_MDIO_CTRL_MASTER_EN |
  17543. + AR7240_MDIO_CTRL_BUSY |
  17544. + AR7240_MDIO_CTRL_CMD_READ;
  17545. +
  17546. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17547. + err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17548. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17549. + if (err)
  17550. + return 0xffff;
  17551. +
  17552. + t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL);
  17553. + return (t & AR7240_MDIO_CTRL_DATA_M);
  17554. +}
  17555. +
  17556. +static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
  17557. + unsigned reg_addr, u16 reg_val)
  17558. +{
  17559. + u32 t;
  17560. + int ret;
  17561. +
  17562. + if (phy_addr >= AR7240_NUM_PHYS)
  17563. + return -EINVAL;
  17564. +
  17565. + t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17566. + (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17567. + AR7240_MDIO_CTRL_MASTER_EN |
  17568. + AR7240_MDIO_CTRL_BUSY |
  17569. + AR7240_MDIO_CTRL_CMD_WRITE |
  17570. + reg_val;
  17571. +
  17572. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17573. + ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17574. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17575. + return ret;
  17576. +}
  17577. +
  17578. +static int ar7240sw_capture_stats(struct ar7240sw *as)
  17579. +{
  17580. + int ret;
  17581. +
  17582. + /* Capture the hardware statistics for all ports */
  17583. + ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0,
  17584. + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
  17585. +
  17586. + /* Wait for the capturing to complete. */
  17587. + ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0,
  17588. + AR7240_MIB_BUSY, 0, 10);
  17589. + return ret;
  17590. +}
  17591. +
  17592. +static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
  17593. +{
  17594. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port),
  17595. + AR7240_PORT_CTRL_STATE_DISABLED);
  17596. +}
  17597. +
  17598. +static int ar7240sw_reset(struct ar7240sw *as)
  17599. +{
  17600. + int ret;
  17601. + int i;
  17602. +
  17603. + /* Set all ports to disabled state. */
  17604. + for (i = 0; i < AR7240_NUM_PORTS; i++)
  17605. + ar7240sw_disable_port(as, i);
  17606. +
  17607. + /* Wait for transmit queues to drain. */
  17608. + msleep(2);
  17609. +
  17610. + /* Reset the switch. */
  17611. + ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL,
  17612. + AR7240_MASK_CTRL_SOFT_RESET);
  17613. +
  17614. + ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL,
  17615. + AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
  17616. + return ret;
  17617. +}
  17618. +
  17619. +static void ar7240sw_setup(struct ar7240sw *as)
  17620. +{
  17621. + /* Enable CPU port, and disable mirror port */
  17622. + ar7240sw_reg_write(as, AR7240_REG_CPU_PORT,
  17623. + AR7240_CPU_PORT_EN |
  17624. + (15 << AR7240_MIRROR_PORT_S));
  17625. +
  17626. + /* Setup TAG priority mapping */
  17627. + ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50);
  17628. +
  17629. + /* Enable ARP frame acknowledge */
  17630. + ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
  17631. +
  17632. + /* Enable Broadcast frames transmitted to the CPU */
  17633. + ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK,
  17634. + AR7240_FLOOD_MASK_BROAD_TO_CPU);
  17635. +
  17636. + /* setup MTU */
  17637. + ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
  17638. + 1536);
  17639. +
  17640. + /* setup Service TAG */
  17641. + ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M,
  17642. + ETH_P_QINQ);
  17643. +}
  17644. +
  17645. +static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port)
  17646. +{
  17647. + u32 ctrl;
  17648. + u32 dest_ports;
  17649. + u32 vlan;
  17650. +
  17651. + ctrl = AR7240_PORT_CTRL_STATE_FORWARD;
  17652. +
  17653. + if (port == AR7240_PORT_CPU) {
  17654. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17655. + AR7240_PORT_STATUS_SPEED_1000 |
  17656. + AR7240_PORT_STATUS_TXFLOW |
  17657. + AR7240_PORT_STATUS_RXFLOW |
  17658. + AR7240_PORT_STATUS_TXMAC |
  17659. + AR7240_PORT_STATUS_RXMAC |
  17660. + AR7240_PORT_STATUS_DUPLEX);
  17661. +
  17662. + /* allow the CPU port to talk to each of the 'real' ports */
  17663. + dest_ports = AR7240_PORT_MASK_BUT(port);
  17664. +
  17665. + /* remove service tag from ingress frames */
  17666. + ctrl |= AR7240_PORT_CTRL_DOUBLE_TAG;
  17667. + } else {
  17668. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17669. + AR7240_PORT_STATUS_LINK_AUTO);
  17670. +
  17671. + /*
  17672. + * allow each of the 'real' ports to only talk to the CPU
  17673. + * port.
  17674. + */
  17675. + dest_ports = AR7240_PORT_MASK(port) |
  17676. + AR7240_PORT_MASK(AR7240_PORT_CPU);
  17677. +
  17678. + /* add service tag to egress frames */
  17679. + ctrl |= (AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG <<
  17680. + AR7240_PORT_CTRL_VLAN_MODE_S);
  17681. + }
  17682. +
  17683. + /* set default VID and and destination ports for this VLAN */
  17684. + vlan = port;
  17685. + vlan |= (dest_ports << AR7240_PORT_VLAN_DEST_PORTS_S);
  17686. +
  17687. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl);
  17688. + ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan);
  17689. +}
  17690. +
  17691. +static char *ar7240_dsa_probe(struct mii_bus *mii, int sw_addr)
  17692. +{
  17693. + struct ar7240sw as;
  17694. + u32 ctrl;
  17695. + u16 phy_id1;
  17696. + u16 phy_id2;
  17697. + u8 ver;
  17698. +
  17699. + ar7240sw_init(&as, mii);
  17700. +
  17701. + ctrl = ar7240sw_reg_read(&as, AR7240_REG_MASK_CTRL);
  17702. +
  17703. + ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
  17704. + if (ver != 1) {
  17705. + pr_err("ar7240_dsa: unsupported chip, ctrl=%08x\n", ctrl);
  17706. + return NULL;
  17707. + }
  17708. +
  17709. + phy_id1 = ar7240sw_phy_read(&as, 0, MII_PHYSID1);
  17710. + phy_id2 = ar7240sw_phy_read(&as, 0, MII_PHYSID2);
  17711. + if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
  17712. + pr_err("ar7240_dsa: unknown phy id '%04x:%04x'\n",
  17713. + phy_id1, phy_id2);
  17714. + return NULL;
  17715. + }
  17716. +
  17717. + return "Atheros AR7240 built-in";
  17718. +}
  17719. +
  17720. +static int ar7240_dsa_setup(struct dsa_switch *ds)
  17721. +{
  17722. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17723. + int i;
  17724. + int ret;
  17725. +
  17726. + ar7240sw_init(as, ds->master_mii_bus);
  17727. +
  17728. + ret = ar7240sw_reset(as);
  17729. + if (ret)
  17730. + return ret;
  17731. +
  17732. + ar7240sw_setup(as);
  17733. +
  17734. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  17735. + if (dsa_is_cpu_port(ds, i) || (ds->phys_port_mask & (1 << i)))
  17736. + ar7240sw_setup_port(as, i);
  17737. + else
  17738. + ar7240sw_disable_port(as, i);
  17739. + }
  17740. +
  17741. + return 0;
  17742. +}
  17743. +
  17744. +static int ar7240_dsa_set_addr(struct dsa_switch *ds, u8 *addr)
  17745. +{
  17746. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17747. + u32 t;
  17748. +
  17749. + t = (addr[4] << 8) | addr[5];
  17750. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
  17751. +
  17752. + t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
  17753. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR1, t);
  17754. +
  17755. + return 0;
  17756. +}
  17757. +
  17758. +static int ar7240_iort_to_phy_addr(int port)
  17759. +{
  17760. + if (port > 0 && port < AR7240_NUM_PORTS)
  17761. + return port - 1;
  17762. +
  17763. + return -EINVAL;
  17764. +}
  17765. +
  17766. +static int ar7240_dsa_phy_read(struct dsa_switch *ds, int port, int regnum)
  17767. +{
  17768. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17769. + int phy_addr;
  17770. +
  17771. + phy_addr = ar7240_iort_to_phy_addr(port);
  17772. + if (phy_addr < 0)
  17773. + return 0xffff;
  17774. +
  17775. + return ar7240sw_phy_read(as, phy_addr, regnum);
  17776. +}
  17777. +
  17778. +static int ar7240_dsa_phy_write(struct dsa_switch *ds, int port, int regnum,
  17779. + u16 val)
  17780. +{
  17781. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17782. + int phy_addr;
  17783. +
  17784. + phy_addr = ar7240_iort_to_phy_addr(port);
  17785. + if (phy_addr < 0)
  17786. + return 0xffff;
  17787. +
  17788. + return ar7240sw_phy_write(as, phy_addr, regnum, val);
  17789. +}
  17790. +
  17791. +static const char *ar7240sw_speed_str(unsigned speed)
  17792. +{
  17793. + switch (speed) {
  17794. + case AR7240_PORT_STATUS_SPEED_10:
  17795. + return "10";
  17796. + case AR7240_PORT_STATUS_SPEED_100:
  17797. + return "100";
  17798. + case AR7240_PORT_STATUS_SPEED_1000:
  17799. + return "1000";
  17800. + }
  17801. +
  17802. + return "????";
  17803. +}
  17804. +
  17805. +static void ar7240_dsa_poll_link(struct dsa_switch *ds)
  17806. +{
  17807. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17808. + int i;
  17809. +
  17810. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  17811. + struct net_device *dev;
  17812. + u32 status;
  17813. + int link;
  17814. + unsigned speed;
  17815. + int duplex;
  17816. +
  17817. + dev = ds->ports[i];
  17818. + if (dev == NULL)
  17819. + continue;
  17820. +
  17821. + link = 0;
  17822. + if (dev->flags & IFF_UP) {
  17823. + status = ar7240sw_reg_read(as,
  17824. + AR7240_REG_PORT_STATUS(i));
  17825. + link = !!(status & AR7240_PORT_STATUS_LINK_UP);
  17826. + }
  17827. +
  17828. + if (!link) {
  17829. + if (netif_carrier_ok(dev)) {
  17830. + pr_info("%s: link down\n", dev->name);
  17831. + netif_carrier_off(dev);
  17832. + }
  17833. + continue;
  17834. + }
  17835. +
  17836. + speed = (status & AR7240_PORT_STATUS_SPEED_M);
  17837. + duplex = (status & AR7240_PORT_STATUS_DUPLEX) ? 1 : 0;
  17838. + if (!netif_carrier_ok(dev)) {
  17839. + pr_info("%s: link up, %sMb/s, %s duplex",
  17840. + dev->name,
  17841. + ar7240sw_speed_str(speed),
  17842. + duplex ? "full" : "half");
  17843. + netif_carrier_on(dev);
  17844. + }
  17845. + }
  17846. +}
  17847. +
  17848. +static const struct ar7240sw_hw_stat ar7240_hw_stats[] = {
  17849. + { "rx_broadcast" , 4, AR7240_STATS_RXBROAD, },
  17850. + { "rx_pause" , 4, AR7240_STATS_RXPAUSE, },
  17851. + { "rx_multicast" , 4, AR7240_STATS_RXMULTI, },
  17852. + { "rx_fcs_error" , 4, AR7240_STATS_RXFCSERR, },
  17853. + { "rx_align_error" , 4, AR7240_STATS_RXALIGNERR, },
  17854. + { "rx_undersize" , 4, AR7240_STATS_RXRUNT, },
  17855. + { "rx_fragments" , 4, AR7240_STATS_RXFRAGMENT, },
  17856. + { "rx_64bytes" , 4, AR7240_STATS_RX64BYTE, },
  17857. + { "rx_65_127bytes" , 4, AR7240_STATS_RX128BYTE, },
  17858. + { "rx_128_255bytes" , 4, AR7240_STATS_RX256BYTE, },
  17859. + { "rx_256_511bytes" , 4, AR7240_STATS_RX512BYTE, },
  17860. + { "rx_512_1023bytes" , 4, AR7240_STATS_RX1024BYTE, },
  17861. + { "rx_1024_1518bytes" , 4, AR7240_STATS_RX1518BYTE, },
  17862. + { "rx_1519_max_bytes" , 4, AR7240_STATS_RXMAXBYTE, },
  17863. + { "rx_oversize" , 4, AR7240_STATS_RXTOOLONG, },
  17864. + { "rx_good_bytes" , 8, AR7240_STATS_RXGOODBYTE, },
  17865. + { "rx_bad_bytes" , 8, AR7240_STATS_RXBADBYTE, },
  17866. + { "rx_overflow" , 4, AR7240_STATS_RXOVERFLOW, },
  17867. + { "filtered" , 4, AR7240_STATS_FILTERED, },
  17868. + { "tx_broadcast" , 4, AR7240_STATS_TXBROAD, },
  17869. + { "tx_pause" , 4, AR7240_STATS_TXPAUSE, },
  17870. + { "tx_multicast" , 4, AR7240_STATS_TXMULTI, },
  17871. + { "tx_underrun" , 4, AR7240_STATS_TXUNDERRUN, },
  17872. + { "tx_64bytes" , 4, AR7240_STATS_TX64BYTE, },
  17873. + { "tx_65_127bytes" , 4, AR7240_STATS_TX128BYTE, },
  17874. + { "tx_128_255bytes" , 4, AR7240_STATS_TX256BYTE, },
  17875. + { "tx_256_511bytes" , 4, AR7240_STATS_TX512BYTE, },
  17876. + { "tx_512_1023bytes" , 4, AR7240_STATS_TX1024BYTE, },
  17877. + { "tx_1024_1518bytes" , 4, AR7240_STATS_TX1518BYTE, },
  17878. + { "tx_1519_max_bytes" , 4, AR7240_STATS_TXMAXBYTE, },
  17879. + { "tx_oversize" , 4, AR7240_STATS_TXOVERSIZE, },
  17880. + { "tx_bytes" , 8, AR7240_STATS_TXBYTE, },
  17881. + { "tx_collisions" , 4, AR7240_STATS_TXCOLLISION, },
  17882. + { "tx_abort_collisions" , 4, AR7240_STATS_TXABORTCOL, },
  17883. + { "tx_multi_collisions" , 4, AR7240_STATS_TXMULTICOL, },
  17884. + { "tx_single_collisions", 4, AR7240_STATS_TXSINGLECOL, },
  17885. + { "tx_excessive_deferred", 4, AR7240_STATS_TXEXCDEFER, },
  17886. + { "tx_deferred" , 4, AR7240_STATS_TXDEFER, },
  17887. + { "tx_late_collisions" , 4, AR7240_STATS_TXLATECOL, },
  17888. +};
  17889. +
  17890. +static void ar7240_dsa_get_strings(struct dsa_switch *ds, int port,
  17891. + uint8_t *data)
  17892. +{
  17893. + int i;
  17894. +
  17895. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  17896. + memcpy(data + i * ETH_GSTRING_LEN,
  17897. + ar7240_hw_stats[i].string, ETH_GSTRING_LEN);
  17898. + }
  17899. +}
  17900. +
  17901. +static void ar7240_dsa_get_ethtool_stats(struct dsa_switch *ds, int port,
  17902. + uint64_t *data)
  17903. +{
  17904. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17905. + int err;
  17906. + int i;
  17907. +
  17908. + mutex_lock(&as->stats_mutex);
  17909. +
  17910. + err = ar7240sw_capture_stats(as);
  17911. + if (err)
  17912. + goto unlock;
  17913. +
  17914. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  17915. + const struct ar7240sw_hw_stat *s = &ar7240_hw_stats[i];
  17916. + u32 reg = AR7240_REG_STATS_BASE(port);
  17917. + u32 low;
  17918. + u32 high;
  17919. +
  17920. + low = ar7240sw_reg_read(as, reg + s->reg);
  17921. + if (s->sizeof_stat == 8)
  17922. + high = ar7240sw_reg_read(as, reg + s->reg);
  17923. + else
  17924. + high = 0;
  17925. +
  17926. + data[i] = (((u64) high) << 32) | low;
  17927. + }
  17928. +
  17929. + unlock:
  17930. + mutex_unlock(&as->stats_mutex);
  17931. +}
  17932. +
  17933. +static int ar7240_dsa_get_sset_count(struct dsa_switch *ds)
  17934. +{
  17935. + return ARRAY_SIZE(ar7240_hw_stats);
  17936. +}
  17937. +
  17938. +static struct dsa_switch_driver ar7240_dsa_driver = {
  17939. + .tag_protocol = htons(ETH_P_QINQ),
  17940. + .priv_size = sizeof(struct ar7240sw),
  17941. + .probe = ar7240_dsa_probe,
  17942. + .setup = ar7240_dsa_setup,
  17943. + .set_addr = ar7240_dsa_set_addr,
  17944. + .phy_read = ar7240_dsa_phy_read,
  17945. + .phy_write = ar7240_dsa_phy_write,
  17946. + .poll_link = ar7240_dsa_poll_link,
  17947. + .get_strings = ar7240_dsa_get_strings,
  17948. + .get_ethtool_stats = ar7240_dsa_get_ethtool_stats,
  17949. + .get_sset_count = ar7240_dsa_get_sset_count,
  17950. +};
  17951. +
  17952. +int __init dsa_ar7240_init(void)
  17953. +{
  17954. + register_switch_driver(&ar7240_dsa_driver);
  17955. + return 0;
  17956. +}
  17957. +module_init(dsa_ar7240_init);
  17958. +
  17959. +void __exit dsa_ar7240_cleanup(void)
  17960. +{
  17961. + unregister_switch_driver(&ar7240_dsa_driver);
  17962. +}
  17963. +module_exit(dsa_ar7240_cleanup);
  17964. diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c
  17965. --- linux-2.6.39.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100
  17966. +++ linux-2.6.39/net/dsa/mv88e6063.c 2011-05-27 14:36:51.000000000 +0200
  17967. @@ -0,0 +1,294 @@
  17968. +/*
  17969. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips
  17970. + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  17971. + *
  17972. + * This driver was base on: net/dsa/mv88e6060.c
  17973. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips
  17974. + * Copyright (c) 2008-2009 Marvell Semiconductor
  17975. + *
  17976. + * This program is free software; you can redistribute it and/or modify
  17977. + * it under the terms of the GNU General Public License as published by
  17978. + * the Free Software Foundation; either version 2 of the License, or
  17979. + * (at your option) any later version.
  17980. + */
  17981. +
  17982. +#include <linux/list.h>
  17983. +#include <linux/netdevice.h>
  17984. +#include <linux/phy.h>
  17985. +#include "dsa_priv.h"
  17986. +
  17987. +#define REG_BASE 0x10
  17988. +#define REG_PHY(p) (REG_BASE + (p))
  17989. +#define REG_PORT(p) (REG_BASE + 8 + (p))
  17990. +#define REG_GLOBAL (REG_BASE + 0x0f)
  17991. +#define NUM_PORTS 7
  17992. +
  17993. +static int reg_read(struct dsa_switch *ds, int addr, int reg)
  17994. +{
  17995. + return mdiobus_read(ds->master_mii_bus, addr, reg);
  17996. +}
  17997. +
  17998. +#define REG_READ(addr, reg) \
  17999. + ({ \
  18000. + int __ret; \
  18001. + \
  18002. + __ret = reg_read(ds, addr, reg); \
  18003. + if (__ret < 0) \
  18004. + return __ret; \
  18005. + __ret; \
  18006. + })
  18007. +
  18008. +
  18009. +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
  18010. +{
  18011. + return mdiobus_write(ds->master_mii_bus, addr, reg, val);
  18012. +}
  18013. +
  18014. +#define REG_WRITE(addr, reg, val) \
  18015. + ({ \
  18016. + int __ret; \
  18017. + \
  18018. + __ret = reg_write(ds, addr, reg, val); \
  18019. + if (__ret < 0) \
  18020. + return __ret; \
  18021. + })
  18022. +
  18023. +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr)
  18024. +{
  18025. + int ret;
  18026. +
  18027. + ret = mdiobus_read(bus, REG_PORT(0), 0x03);
  18028. + if (ret >= 0) {
  18029. + ret &= 0xfff0;
  18030. + if (ret == 0x1530)
  18031. + return "Marvell 88E6063";
  18032. + }
  18033. +
  18034. + return NULL;
  18035. +}
  18036. +
  18037. +static int mv88e6063_switch_reset(struct dsa_switch *ds)
  18038. +{
  18039. + int i;
  18040. + int ret;
  18041. +
  18042. + /*
  18043. + * Set all ports to the disabled state.
  18044. + */
  18045. + for (i = 0; i < NUM_PORTS; i++) {
  18046. + ret = REG_READ(REG_PORT(i), 0x04);
  18047. + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
  18048. + }
  18049. +
  18050. + /*
  18051. + * Wait for transmit queues to drain.
  18052. + */
  18053. + msleep(2);
  18054. +
  18055. + /*
  18056. + * Reset the switch.
  18057. + */
  18058. + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130);
  18059. +
  18060. + /*
  18061. + * Wait up to one second for reset to complete.
  18062. + */
  18063. + for (i = 0; i < 1000; i++) {
  18064. + ret = REG_READ(REG_GLOBAL, 0x00);
  18065. + if ((ret & 0x8000) == 0x0000)
  18066. + break;
  18067. +
  18068. + msleep(1);
  18069. + }
  18070. + if (i == 1000)
  18071. + return -ETIMEDOUT;
  18072. +
  18073. + return 0;
  18074. +}
  18075. +
  18076. +static int mv88e6063_setup_global(struct dsa_switch *ds)
  18077. +{
  18078. + /*
  18079. + * Disable discarding of frames with excessive collisions,
  18080. + * set the maximum frame size to 1536 bytes, and mask all
  18081. + * interrupt sources.
  18082. + */
  18083. + REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
  18084. +
  18085. + /*
  18086. + * Enable automatic address learning, set the address
  18087. + * database size to 1024 entries, and set the default aging
  18088. + * time to 5 minutes.
  18089. + */
  18090. + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
  18091. +
  18092. + return 0;
  18093. +}
  18094. +
  18095. +static int mv88e6063_setup_port(struct dsa_switch *ds, int p)
  18096. +{
  18097. + int addr = REG_PORT(p);
  18098. +
  18099. + /*
  18100. + * Do not force flow control, disable Ingress and Egress
  18101. + * Header tagging, disable VLAN tunneling, and set the port
  18102. + * state to Forwarding. Additionally, if this is the CPU
  18103. + * port, enable Ingress and Egress Trailer tagging mode.
  18104. + */
  18105. + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003);
  18106. +
  18107. + /*
  18108. + * Port based VLAN map: give each port its own address
  18109. + * database, allow the CPU port to talk to each of the 'real'
  18110. + * ports, and allow each of the 'real' ports to only talk to
  18111. + * the CPU port.
  18112. + */
  18113. + REG_WRITE(addr, 0x06,
  18114. + ((p & 0xf) << 12) |
  18115. + (dsa_is_cpu_port(ds, p) ?
  18116. + ds->phys_port_mask :
  18117. + (1 << ds->dst->cpu_port)));
  18118. +
  18119. + /*
  18120. + * Port Association Vector: when learning source addresses
  18121. + * of packets, add the address to the address database using
  18122. + * a port bitmap that has only the bit for this port set and
  18123. + * the other bits clear.
  18124. + */
  18125. + REG_WRITE(addr, 0x0b, 1 << p);
  18126. +
  18127. + return 0;
  18128. +}
  18129. +
  18130. +static int mv88e6063_setup(struct dsa_switch *ds)
  18131. +{
  18132. + int i;
  18133. + int ret;
  18134. +
  18135. + ret = mv88e6063_switch_reset(ds);
  18136. + if (ret < 0)
  18137. + return ret;
  18138. +
  18139. + /* @@@ initialise atu */
  18140. +
  18141. + ret = mv88e6063_setup_global(ds);
  18142. + if (ret < 0)
  18143. + return ret;
  18144. +
  18145. + for (i = 0; i < NUM_PORTS; i++) {
  18146. + ret = mv88e6063_setup_port(ds, i);
  18147. + if (ret < 0)
  18148. + return ret;
  18149. + }
  18150. +
  18151. + return 0;
  18152. +}
  18153. +
  18154. +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr)
  18155. +{
  18156. + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
  18157. + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
  18158. + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
  18159. +
  18160. + return 0;
  18161. +}
  18162. +
  18163. +static int mv88e6063_port_to_phy_addr(int port)
  18164. +{
  18165. + if (port >= 0 && port <= NUM_PORTS)
  18166. + return REG_PHY(port);
  18167. + return -1;
  18168. +}
  18169. +
  18170. +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum)
  18171. +{
  18172. + int addr;
  18173. +
  18174. + addr = mv88e6063_port_to_phy_addr(port);
  18175. + if (addr == -1)
  18176. + return 0xffff;
  18177. +
  18178. + return reg_read(ds, addr, regnum);
  18179. +}
  18180. +
  18181. +static int
  18182. +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
  18183. +{
  18184. + int addr;
  18185. +
  18186. + addr = mv88e6063_port_to_phy_addr(port);
  18187. + if (addr == -1)
  18188. + return 0xffff;
  18189. +
  18190. + return reg_write(ds, addr, regnum, val);
  18191. +}
  18192. +
  18193. +static void mv88e6063_poll_link(struct dsa_switch *ds)
  18194. +{
  18195. + int i;
  18196. +
  18197. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  18198. + struct net_device *dev;
  18199. + int uninitialized_var(port_status);
  18200. + int link;
  18201. + int speed;
  18202. + int duplex;
  18203. + int fc;
  18204. +
  18205. + dev = ds->ports[i];
  18206. + if (dev == NULL)
  18207. + continue;
  18208. +
  18209. + link = 0;
  18210. + if (dev->flags & IFF_UP) {
  18211. + port_status = reg_read(ds, REG_PORT(i), 0x00);
  18212. + if (port_status < 0)
  18213. + continue;
  18214. +
  18215. + link = !!(port_status & 0x1000);
  18216. + }
  18217. +
  18218. + if (!link) {
  18219. + if (netif_carrier_ok(dev)) {
  18220. + printk(KERN_INFO "%s: link down\n", dev->name);
  18221. + netif_carrier_off(dev);
  18222. + }
  18223. + continue;
  18224. + }
  18225. +
  18226. + speed = (port_status & 0x0100) ? 100 : 10;
  18227. + duplex = (port_status & 0x0200) ? 1 : 0;
  18228. + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
  18229. +
  18230. + if (!netif_carrier_ok(dev)) {
  18231. + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
  18232. + "flow control %sabled\n", dev->name,
  18233. + speed, duplex ? "full" : "half",
  18234. + fc ? "en" : "dis");
  18235. + netif_carrier_on(dev);
  18236. + }
  18237. + }
  18238. +}
  18239. +
  18240. +static struct dsa_switch_driver mv88e6063_switch_driver = {
  18241. + .tag_protocol = htons(ETH_P_TRAILER),
  18242. + .probe = mv88e6063_probe,
  18243. + .setup = mv88e6063_setup,
  18244. + .set_addr = mv88e6063_set_addr,
  18245. + .phy_read = mv88e6063_phy_read,
  18246. + .phy_write = mv88e6063_phy_write,
  18247. + .poll_link = mv88e6063_poll_link,
  18248. +};
  18249. +
  18250. +static int __init mv88e6063_init(void)
  18251. +{
  18252. + register_switch_driver(&mv88e6063_switch_driver);
  18253. + return 0;
  18254. +}
  18255. +module_init(mv88e6063_init);
  18256. +
  18257. +static void __exit mv88e6063_cleanup(void)
  18258. +{
  18259. + unregister_switch_driver(&mv88e6063_switch_driver);
  18260. +}
  18261. +module_exit(mv88e6063_cleanup);
  18262. diff -Nur linux-2.6.39.orig/net/dsa/tag_qinq.c linux-2.6.39/net/dsa/tag_qinq.c
  18263. --- linux-2.6.39.orig/net/dsa/tag_qinq.c 1970-01-01 01:00:00.000000000 +0100
  18264. +++ linux-2.6.39/net/dsa/tag_qinq.c 2011-05-27 14:36:51.000000000 +0200
  18265. @@ -0,0 +1,127 @@
  18266. +/*
  18267. + * net/dsa/tag_qinq.c - QinQ tag format handling
  18268. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  18269. + *
  18270. + * This file was based on:
  18271. + * net/dsa/tag_edsa.c - Ethertype DSA tagging
  18272. + * Copyright (c) 2008-2009 Marvell Semiconductor
  18273. + *
  18274. + * This program is free software; you can redistribute it and/or modify
  18275. + * it under the terms of the GNU General Public License as published by
  18276. + * the Free Software Foundation; either version 2 of the License, or
  18277. + * (at your option) any later version.
  18278. + */
  18279. +
  18280. +#include <linux/etherdevice.h>
  18281. +#include <linux/list.h>
  18282. +#include <linux/netdevice.h>
  18283. +#include <linux/if_vlan.h>
  18284. +
  18285. +#include "dsa_priv.h"
  18286. +
  18287. +netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev)
  18288. +{
  18289. + struct dsa_slave_priv *p = netdev_priv(dev);
  18290. + struct vlan_ethhdr *veth;
  18291. + unsigned int len;
  18292. + int ret;
  18293. +
  18294. + if (skb_cow_head(skb, VLAN_HLEN) < 0)
  18295. + goto out_free_skb;
  18296. +
  18297. + veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
  18298. +
  18299. + /* Move the mac addresses to the beginning of the new header. */
  18300. + memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
  18301. + skb->mac_header -= VLAN_HLEN;
  18302. +
  18303. + /* setup VLAN header fields */
  18304. + veth->h_vlan_proto = htons(ETH_P_QINQ);
  18305. + veth->h_vlan_TCI = htons(p->port);
  18306. +
  18307. + len = skb->len;
  18308. + skb->protocol = htons(ETH_P_QINQ);
  18309. + skb->dev = p->parent->dst->master_netdev;
  18310. +
  18311. + ret = dev_queue_xmit(skb);
  18312. + if (unlikely(ret != NET_XMIT_SUCCESS))
  18313. + goto out_dropped;
  18314. +
  18315. + dev->stats.tx_packets++;
  18316. + dev->stats.tx_bytes += len;
  18317. +
  18318. + return NETDEV_TX_OK;
  18319. +
  18320. + out_free_skb:
  18321. + kfree_skb(skb);
  18322. + out_dropped:
  18323. + dev->stats.tx_dropped++;
  18324. + return NETDEV_TX_OK;
  18325. +}
  18326. +
  18327. +static int qinq_rcv(struct sk_buff *skb, struct net_device *dev,
  18328. + struct packet_type *pt, struct net_device *orig_dev)
  18329. +{
  18330. + struct dsa_switch_tree *dst;
  18331. + struct dsa_switch *ds;
  18332. + struct vlan_hdr *vhdr;
  18333. + int source_port;
  18334. +
  18335. + dst = dev->dsa_ptr;
  18336. + if (unlikely(dst == NULL))
  18337. + goto out_drop;
  18338. + ds = dst->ds[0];
  18339. +
  18340. + skb = skb_unshare(skb, GFP_ATOMIC);
  18341. + if (skb == NULL)
  18342. + goto out;
  18343. +
  18344. + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
  18345. + goto out_drop;
  18346. +
  18347. + vhdr = (struct vlan_hdr *)skb->data;
  18348. + source_port = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
  18349. + if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
  18350. + goto out_drop;
  18351. +
  18352. + /* Remove the outermost VLAN tag and update checksum. */
  18353. + skb_pull_rcsum(skb, VLAN_HLEN);
  18354. + memmove(skb->data - ETH_HLEN,
  18355. + skb->data - ETH_HLEN - VLAN_HLEN,
  18356. + 2 * ETH_ALEN);
  18357. +
  18358. + skb->dev = ds->ports[source_port];
  18359. + skb_push(skb, ETH_HLEN);
  18360. + skb->pkt_type = PACKET_HOST;
  18361. + skb->protocol = eth_type_trans(skb, skb->dev);
  18362. +
  18363. + skb->dev->stats.rx_packets++;
  18364. + skb->dev->stats.rx_bytes += skb->len;
  18365. +
  18366. + netif_receive_skb(skb);
  18367. +
  18368. + return 0;
  18369. +
  18370. + out_drop:
  18371. + kfree_skb(skb);
  18372. + out:
  18373. + return 0;
  18374. +}
  18375. +
  18376. +static struct packet_type qinq_packet_type __read_mostly = {
  18377. + .type = cpu_to_be16(ETH_P_QINQ),
  18378. + .func = qinq_rcv,
  18379. +};
  18380. +
  18381. +static int __init qinq_init_module(void)
  18382. +{
  18383. + dev_add_pack(&qinq_packet_type);
  18384. + return 0;
  18385. +}
  18386. +module_init(qinq_init_module);
  18387. +
  18388. +static void __exit qinq_cleanup_module(void)
  18389. +{
  18390. + dev_remove_pack(&qinq_packet_type);
  18391. +}
  18392. +module_exit(qinq_cleanup_module);