ar71xx.patch 260 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913
  1. diff -Nur linux-2.6.29.1.orig/arch/mips/Kconfig linux-2.6.29.1/arch/mips/Kconfig
  2. --- linux-2.6.29.1.orig/arch/mips/Kconfig 2009-04-02 22:55:27.000000000 +0200
  3. +++ linux-2.6.29.1/arch/mips/Kconfig 2009-04-13 14:27:23.734393467 +0200
  4. @@ -22,6 +22,23 @@
  5. config MACH_ALCHEMY
  6. bool "Alchemy processor based machines"
  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 BASLER_EXCITE
  25. bool "Basler eXcite smart camera"
  26. select CEVT_R4K
  27. @@ -640,6 +657,7 @@
  28. endchoice
  29. source "arch/mips/alchemy/Kconfig"
  30. +source "arch/mips/ar71xx/Kconfig"
  31. source "arch/mips/basler/excite/Kconfig"
  32. source "arch/mips/jazz/Kconfig"
  33. source "arch/mips/lasat/Kconfig"
  34. @@ -810,6 +828,9 @@
  35. config SYNC_R4K
  36. bool
  37. +config MIPS_MACHINE
  38. + def_bool n
  39. +
  40. config NO_IOPORT
  41. def_bool n
  42. diff -Nur linux-2.6.29.1.orig/arch/mips/Makefile linux-2.6.29.1/arch/mips/Makefile
  43. --- linux-2.6.29.1.orig/arch/mips/Makefile 2009-04-02 22:55:27.000000000 +0200
  44. +++ linux-2.6.29.1/arch/mips/Makefile 2009-04-13 14:27:34.483063970 +0200
  45. @@ -602,6 +602,14 @@
  46. load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
  47. endif
  48. +#
  49. +# Atheros AR71xx
  50. +#
  51. +core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
  52. +cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
  53. +load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
  54. +
  55. +
  56. cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
  57. drivers-$(CONFIG_PCI) += arch/mips/pci/
  58. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/Kconfig linux-2.6.29.1/arch/mips/ar71xx/Kconfig
  59. --- linux-2.6.29.1.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  60. +++ linux-2.6.29.1/arch/mips/ar71xx/Kconfig 2009-04-13 14:27:34.483063970 +0200
  61. @@ -0,0 +1,64 @@
  62. +if ATHEROS_AR71XX
  63. +
  64. +config AR71XX_EARLY_SERIAL
  65. + bool "Use early serial console"
  66. + default n
  67. +
  68. +menu "Atheros AR71xx machine selection"
  69. +
  70. +config AR71XX_MACH_AP81
  71. + bool "Atheros AP81 board support"
  72. + default y
  73. +
  74. +config AR71XX_MACH_AP83
  75. + bool "Atheros AP83 board support"
  76. + default y
  77. +
  78. +config AR71XX_MACH_PB42
  79. + bool "Atheros PB42 board support"
  80. + default y
  81. +
  82. +config AR71XX_MACH_AW_NR580
  83. + bool "AzureWave AW-NR580 board support"
  84. + default y
  85. +
  86. +config AR71XX_MACH_GENERIC
  87. + bool "Generic AR71xx based machine support"
  88. + default y
  89. +
  90. +config AR71XX_MACH_WP543
  91. + bool "Compex WP543 board support"
  92. + select MYLOADER
  93. + default y
  94. +
  95. +config AR71XX_MACH_RB_4XX
  96. + bool "MikroTik RouterBOARD 4xx series support"
  97. + default y
  98. +
  99. +config AR71XX_MACH_WNR2000
  100. + bool "NETGEAR WNR2000 board support"
  101. + default y
  102. +
  103. +config AR71XX_MACH_MZK_W04NU
  104. + bool "Planex MZK-W04NU board support"
  105. + default y
  106. +
  107. +config AR71XX_MACH_MZK_W300NH
  108. + bool "Planex MZK-W300NH board support"
  109. + default y
  110. +
  111. +config AR71XX_MACH_TL_WR941ND
  112. + bool "TP-LINK TL-WR941ND support"
  113. + default y
  114. +
  115. +config AR71XX_MACH_TEW_632BRP
  116. + bool "TRENDnet TEW-632BRP support"
  117. + default y
  118. +
  119. +config AR71XX_MACH_UBNT
  120. + bool "Ubiquiti AR71xx based boards support"
  121. + default y
  122. +
  123. +endmenu
  124. +
  125. +endif
  126. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/Makefile linux-2.6.29.1/arch/mips/ar71xx/Makefile
  127. --- linux-2.6.29.1.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  128. +++ linux-2.6.29.1/arch/mips/ar71xx/Makefile 2009-04-13 14:27:34.487064480 +0200
  129. @@ -0,0 +1,25 @@
  130. +#
  131. +# Makefile for the Atheros AR71xx SoC specific parts of the kernel
  132. +#
  133. +# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  134. +# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  135. +#
  136. +# This program is free software; you can redistribute it and/or modify it
  137. +# under the terms of the GNU General Public License version 2 as published
  138. +# by the Free Software Foundation.
  139. +
  140. +obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o
  141. +
  142. +obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o
  143. +obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o
  144. +obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o
  145. +obj-$(CONFIG_AR71XX_MACH_GENERIC) += mach-generic.o
  146. +obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o
  147. +obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o
  148. +obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o
  149. +obj-$(CONFIG_AR71XX_MACH_RB_4XX) += mach-rb-4xx.o
  150. +obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o
  151. +obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o
  152. +obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o
  153. +obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o
  154. +obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o
  155. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.29.1/arch/mips/ar71xx/ar71xx.c
  156. --- linux-2.6.29.1.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  157. +++ linux-2.6.29.1/arch/mips/ar71xx/ar71xx.c 2009-04-13 14:27:34.487064480 +0200
  158. @@ -0,0 +1,100 @@
  159. +/*
  160. + * AR71xx SoC routines
  161. + *
  162. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  163. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  164. + *
  165. + * This program is free software; you can redistribute it and/or modify it
  166. + * under the terms of the GNU General Public License version 2 as published
  167. + * by the Free Software Foundation.
  168. + */
  169. +
  170. +#include <linux/kernel.h>
  171. +#include <linux/module.h>
  172. +#include <linux/types.h>
  173. +
  174. +#include <asm/mach-ar71xx/ar71xx.h>
  175. +
  176. +void __iomem *ar71xx_ddr_base;
  177. +EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
  178. +
  179. +void __iomem *ar71xx_pll_base;
  180. +EXPORT_SYMBOL_GPL(ar71xx_pll_base);
  181. +
  182. +void __iomem *ar71xx_reset_base;
  183. +EXPORT_SYMBOL_GPL(ar71xx_reset_base);
  184. +
  185. +void __iomem *ar71xx_gpio_base;
  186. +EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
  187. +
  188. +void __iomem *ar71xx_usb_ctrl_base;
  189. +EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
  190. +
  191. +void ar71xx_device_stop(u32 mask)
  192. +{
  193. + unsigned long flags;
  194. + u32 t;
  195. +
  196. + switch (ar71xx_soc) {
  197. + case AR71XX_SOC_AR7130:
  198. + case AR71XX_SOC_AR7141:
  199. + case AR71XX_SOC_AR7161:
  200. + local_irq_save(flags);
  201. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  202. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
  203. + local_irq_restore(flags);
  204. + break;
  205. +
  206. + case AR71XX_SOC_AR9130:
  207. + case AR71XX_SOC_AR9132:
  208. + local_irq_save(flags);
  209. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  210. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
  211. + local_irq_restore(flags);
  212. + break;
  213. +
  214. + default:
  215. + BUG();
  216. + }
  217. +}
  218. +EXPORT_SYMBOL_GPL(ar71xx_device_stop);
  219. +
  220. +void ar71xx_device_start(u32 mask)
  221. +{
  222. + unsigned long flags;
  223. + u32 t;
  224. +
  225. + switch (ar71xx_soc) {
  226. + case AR71XX_SOC_AR7130:
  227. + case AR71XX_SOC_AR7141:
  228. + case AR71XX_SOC_AR7161:
  229. + local_irq_save(flags);
  230. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  231. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
  232. + local_irq_restore(flags);
  233. + break;
  234. +
  235. + case AR71XX_SOC_AR9130:
  236. + case AR71XX_SOC_AR9132:
  237. + local_irq_save(flags);
  238. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  239. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
  240. + local_irq_restore(flags);
  241. + break;
  242. +
  243. + default:
  244. + BUG();
  245. + }
  246. +}
  247. +EXPORT_SYMBOL_GPL(ar71xx_device_start);
  248. +
  249. +void ar71xx_ddr_flush(u32 reg)
  250. +{
  251. + ar71xx_ddr_wr(reg, 1);
  252. + while ((ar71xx_ddr_rr(reg) & 0x1));
  253. +
  254. + ar71xx_ddr_wr(reg, 1);
  255. + while ((ar71xx_ddr_rr(reg) & 0x1));
  256. +}
  257. +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
  258. +
  259. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/devices.c linux-2.6.29.1/arch/mips/ar71xx/devices.c
  260. --- linux-2.6.29.1.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100
  261. +++ linux-2.6.29.1/arch/mips/ar71xx/devices.c 2009-04-13 14:27:34.491064431 +0200
  262. @@ -0,0 +1,675 @@
  263. +/*
  264. + * Atheros AR71xx SoC platform devices
  265. + *
  266. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  267. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  268. + *
  269. + * Parts of this file are based on Atheros' 2.6.15 BSP
  270. + *
  271. + * This program is free software; you can redistribute it and/or modify it
  272. + * under the terms of the GNU General Public License version 2 as published
  273. + * by the Free Software Foundation.
  274. + */
  275. +
  276. +#include <linux/kernel.h>
  277. +#include <linux/init.h>
  278. +#include <linux/delay.h>
  279. +#include <linux/dma-mapping.h>
  280. +#include <linux/etherdevice.h>
  281. +#include <linux/platform_device.h>
  282. +#include <linux/serial_8250.h>
  283. +#include <linux/ath9k_platform.h>
  284. +
  285. +#include <asm/mach-ar71xx/ar71xx.h>
  286. +
  287. +#include "devices.h"
  288. +
  289. +static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
  290. +
  291. +/*
  292. + * OHCI (USB full speed host controller)
  293. + */
  294. +static struct resource ar71xx_ohci_resources[] = {
  295. + [0] = {
  296. + .start = AR71XX_OHCI_BASE,
  297. + .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
  298. + .flags = IORESOURCE_MEM,
  299. + },
  300. + [1] = {
  301. + .start = AR71XX_MISC_IRQ_OHCI,
  302. + .end = AR71XX_MISC_IRQ_OHCI,
  303. + .flags = IORESOURCE_IRQ,
  304. + },
  305. +};
  306. +
  307. +static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
  308. +static struct platform_device ar71xx_ohci_device = {
  309. + .name = "ar71xx-ohci",
  310. + .id = -1,
  311. + .resource = ar71xx_ohci_resources,
  312. + .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
  313. + .dev = {
  314. + .dma_mask = &ar71xx_ohci_dmamask,
  315. + .coherent_dma_mask = DMA_BIT_MASK(32),
  316. + },
  317. +};
  318. +
  319. +/*
  320. + * EHCI (USB full speed host controller)
  321. + */
  322. +static struct resource ar71xx_ehci_resources[] = {
  323. + [0] = {
  324. + .start = AR71XX_EHCI_BASE,
  325. + .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
  326. + .flags = IORESOURCE_MEM,
  327. + },
  328. + [1] = {
  329. + .start = AR71XX_CPU_IRQ_USB,
  330. + .end = AR71XX_CPU_IRQ_USB,
  331. + .flags = IORESOURCE_IRQ,
  332. + },
  333. +};
  334. +
  335. +
  336. +static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
  337. +static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
  338. +
  339. +static struct platform_device ar71xx_ehci_device = {
  340. + .name = "ar71xx-ehci",
  341. + .id = -1,
  342. + .resource = ar71xx_ehci_resources,
  343. + .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
  344. + .dev = {
  345. + .dma_mask = &ar71xx_ehci_dmamask,
  346. + .coherent_dma_mask = DMA_BIT_MASK(32),
  347. + .platform_data = &ar71xx_ehci_data,
  348. + },
  349. +};
  350. +
  351. +#define AR71XX_USB_RESET_MASK \
  352. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
  353. + | RESET_MODULE_USB_OHCI_DLL)
  354. +
  355. +static void ar71xx_usb_setup(void)
  356. +{
  357. + ar71xx_device_stop(AR71XX_USB_RESET_MASK);
  358. + mdelay(1000);
  359. + ar71xx_device_start(AR71XX_USB_RESET_MASK);
  360. +
  361. + /* Turning on the Buff and Desc swap bits */
  362. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
  363. +
  364. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  365. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
  366. +
  367. + mdelay(900);
  368. +}
  369. +
  370. +static void ar91xx_usb_setup(void)
  371. +{
  372. + ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
  373. + mdelay(10);
  374. +
  375. + ar71xx_device_start(RESET_MODULE_USB_HOST);
  376. + mdelay(10);
  377. +
  378. + ar71xx_device_start(RESET_MODULE_USB_PHY);
  379. + mdelay(10);
  380. +}
  381. +
  382. +void __init ar71xx_add_device_usb(void)
  383. +{
  384. + switch (ar71xx_soc) {
  385. + case AR71XX_SOC_AR7130:
  386. + case AR71XX_SOC_AR7141:
  387. + case AR71XX_SOC_AR7161:
  388. + ar71xx_usb_setup();
  389. + platform_device_register(&ar71xx_ohci_device);
  390. + platform_device_register(&ar71xx_ehci_device);
  391. + break;
  392. +
  393. + case AR71XX_SOC_AR9130:
  394. + case AR71XX_SOC_AR9132:
  395. + ar91xx_usb_setup();
  396. + ar71xx_ehci_data.is_ar91xx = 1;
  397. + platform_device_register(&ar71xx_ehci_device);
  398. + break;
  399. +
  400. + default:
  401. + BUG();
  402. + }
  403. +}
  404. +
  405. +#ifndef CONFIG_AR71XX_EARLY_SERIAL
  406. +static struct resource ar71xx_uart_resources[] = {
  407. + {
  408. + .start = AR71XX_UART_BASE,
  409. + .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
  410. + .flags = IORESOURCE_MEM,
  411. + },
  412. +};
  413. +
  414. +#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
  415. +static struct plat_serial8250_port ar71xx_uart_data[] = {
  416. + {
  417. + .mapbase = AR71XX_UART_BASE,
  418. + .irq = AR71XX_MISC_IRQ_UART,
  419. + .flags = AR71XX_UART_FLAGS,
  420. + .iotype = UPIO_MEM32,
  421. + .regshift = 2,
  422. + }, {
  423. + /* terminating entry */
  424. + }
  425. +};
  426. +
  427. +static struct platform_device ar71xx_uart_device = {
  428. + .name = "serial8250",
  429. + .id = PLAT8250_DEV_PLATFORM,
  430. + .resource = ar71xx_uart_resources,
  431. + .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
  432. + .dev = {
  433. + .platform_data = ar71xx_uart_data
  434. + },
  435. +};
  436. +
  437. +void __init ar71xx_add_device_uart(void)
  438. +{
  439. + ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
  440. + platform_device_register(&ar71xx_uart_device);
  441. +}
  442. +#endif /* CONFIG_AR71XX_EARLY_SERIAL */
  443. +
  444. +static struct resource ar71xx_mdio_resources[] = {
  445. + {
  446. + .name = "mdio_base",
  447. + .flags = IORESOURCE_MEM,
  448. + .start = AR71XX_GE0_BASE + 0x20,
  449. + .end = AR71XX_GE0_BASE + 0x38 - 1,
  450. + }
  451. +};
  452. +
  453. +static struct ag71xx_mdio_platform_data ar71xx_mdio_data = {
  454. + .phy_mask = 0xffffffff,
  455. +};
  456. +
  457. +static struct platform_device ar71xx_mdio_device = {
  458. + .name = "ag71xx-mdio",
  459. + .id = -1,
  460. + .resource = ar71xx_mdio_resources,
  461. + .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
  462. + .dev = {
  463. + .platform_data = &ar71xx_mdio_data,
  464. + },
  465. +};
  466. +
  467. +void __init ar71xx_add_device_mdio(u32 phy_mask)
  468. +{
  469. + ar71xx_mdio_data.phy_mask = phy_mask;
  470. + platform_device_register(&ar71xx_mdio_device);
  471. +}
  472. +
  473. +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
  474. +{
  475. + void __iomem *base;
  476. + u32 t;
  477. +
  478. + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
  479. +
  480. + t = __raw_readl(base + cfg_reg);
  481. + t &= ~(3 << shift);
  482. + t |= (2 << shift);
  483. + __raw_writel(t, base + cfg_reg);
  484. + udelay(100);
  485. +
  486. + __raw_writel(pll_val, base + pll_reg);
  487. +
  488. + t |= (3 << shift);
  489. + __raw_writel(t, base + cfg_reg);
  490. + udelay(100);
  491. +
  492. + t &= ~(3 << shift);
  493. + __raw_writel(t, base + cfg_reg);
  494. + udelay(100);
  495. +
  496. + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
  497. + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
  498. +
  499. + iounmap(base);
  500. +}
  501. +
  502. +static void ar71xx_set_pll_ge0(u32 val)
  503. +{
  504. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
  505. + val, AR71XX_ETH0_PLL_SHIFT);
  506. +}
  507. +
  508. +static void ar71xx_set_pll_ge1(u32 val)
  509. +{
  510. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
  511. + val, AR71XX_ETH1_PLL_SHIFT);
  512. +}
  513. +
  514. +static void ar91xx_set_pll_ge0(u32 val)
  515. +{
  516. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
  517. + val, AR91XX_ETH0_PLL_SHIFT);
  518. +}
  519. +
  520. +static void ar91xx_set_pll_ge1(u32 val)
  521. +{
  522. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
  523. + val, AR91XX_ETH1_PLL_SHIFT);
  524. +}
  525. +
  526. +static void ar71xx_ddr_flush_ge0(void)
  527. +{
  528. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
  529. +}
  530. +
  531. +static void ar71xx_ddr_flush_ge1(void)
  532. +{
  533. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
  534. +}
  535. +
  536. +static void ar91xx_ddr_flush_ge0(void)
  537. +{
  538. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
  539. +}
  540. +
  541. +static void ar91xx_ddr_flush_ge1(void)
  542. +{
  543. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
  544. +}
  545. +
  546. +static struct resource ar71xx_eth0_resources[] = {
  547. + {
  548. + .name = "mac_base",
  549. + .flags = IORESOURCE_MEM,
  550. + .start = AR71XX_GE0_BASE,
  551. + .end = AR71XX_GE0_BASE + 0x20 - 1,
  552. + }, {
  553. + .name = "mac_base2",
  554. + .flags = IORESOURCE_MEM,
  555. + .start = AR71XX_GE0_BASE + 0x38,
  556. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  557. + }, {
  558. + .name = "mii_ctrl",
  559. + .flags = IORESOURCE_MEM,
  560. + .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
  561. + .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
  562. + }, {
  563. + .name = "mac_irq",
  564. + .flags = IORESOURCE_IRQ,
  565. + .start = AR71XX_CPU_IRQ_GE0,
  566. + .end = AR71XX_CPU_IRQ_GE0,
  567. + },
  568. +};
  569. +
  570. +struct ag71xx_platform_data ar71xx_eth0_data = {
  571. + .reset_bit = RESET_MODULE_GE0_MAC,
  572. +};
  573. +
  574. +static struct platform_device ar71xx_eth0_device = {
  575. + .name = "ag71xx",
  576. + .id = 0,
  577. + .resource = ar71xx_eth0_resources,
  578. + .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
  579. + .dev = {
  580. + .platform_data = &ar71xx_eth0_data,
  581. + },
  582. +};
  583. +
  584. +static struct resource ar71xx_eth1_resources[] = {
  585. + {
  586. + .name = "mac_base",
  587. + .flags = IORESOURCE_MEM,
  588. + .start = AR71XX_GE1_BASE,
  589. + .end = AR71XX_GE1_BASE + 0x20 - 1,
  590. + }, {
  591. + .name = "mac_base2",
  592. + .flags = IORESOURCE_MEM,
  593. + .start = AR71XX_GE1_BASE + 0x38,
  594. + .end = AR71XX_GE1_BASE + 0x200 - 1,
  595. + }, {
  596. + .name = "mii_ctrl",
  597. + .flags = IORESOURCE_MEM,
  598. + .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
  599. + .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
  600. + }, {
  601. + .name = "mac_irq",
  602. + .flags = IORESOURCE_IRQ,
  603. + .start = AR71XX_CPU_IRQ_GE1,
  604. + .end = AR71XX_CPU_IRQ_GE1,
  605. + },
  606. +};
  607. +
  608. +struct ag71xx_platform_data ar71xx_eth1_data = {
  609. + .reset_bit = RESET_MODULE_GE1_MAC,
  610. +};
  611. +
  612. +static struct platform_device ar71xx_eth1_device = {
  613. + .name = "ag71xx",
  614. + .id = 1,
  615. + .resource = ar71xx_eth1_resources,
  616. + .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
  617. + .dev = {
  618. + .platform_data = &ar71xx_eth1_data,
  619. + },
  620. +};
  621. +
  622. +static int ar71xx_eth_instance __initdata;
  623. +void __init ar71xx_add_device_eth(unsigned int id)
  624. +{
  625. + struct platform_device *pdev;
  626. + struct ag71xx_platform_data *pdata;
  627. +
  628. + switch (id) {
  629. + case 0:
  630. + switch (ar71xx_eth0_data.phy_if_mode) {
  631. + case PHY_INTERFACE_MODE_MII:
  632. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
  633. + break;
  634. + case PHY_INTERFACE_MODE_GMII:
  635. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
  636. + break;
  637. + case PHY_INTERFACE_MODE_RGMII:
  638. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
  639. + break;
  640. + case PHY_INTERFACE_MODE_RMII:
  641. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
  642. + break;
  643. + default:
  644. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  645. + "for eth0\n");
  646. + return;
  647. + }
  648. + pdev = &ar71xx_eth0_device;
  649. + break;
  650. + case 1:
  651. + switch (ar71xx_eth1_data.phy_if_mode) {
  652. + case PHY_INTERFACE_MODE_RMII:
  653. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
  654. + break;
  655. + case PHY_INTERFACE_MODE_RGMII:
  656. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
  657. + break;
  658. + default:
  659. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  660. + "for eth1\n");
  661. + return;
  662. + }
  663. + pdev = &ar71xx_eth1_device;
  664. + break;
  665. + default:
  666. + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
  667. + return;
  668. + }
  669. +
  670. + pdata = pdev->dev.platform_data;
  671. +
  672. + switch (ar71xx_soc) {
  673. + case AR71XX_SOC_AR7130:
  674. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  675. + : ar71xx_ddr_flush_ge0;
  676. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  677. + : ar71xx_set_pll_ge0;
  678. + break;
  679. +
  680. + case AR71XX_SOC_AR7141:
  681. + case AR71XX_SOC_AR7161:
  682. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  683. + : ar71xx_ddr_flush_ge0;
  684. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  685. + : ar71xx_set_pll_ge0;
  686. + pdata->has_gbit = 1;
  687. + break;
  688. +
  689. + case AR71XX_SOC_AR9130:
  690. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  691. + : ar91xx_ddr_flush_ge0;
  692. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  693. + : ar91xx_set_pll_ge0;
  694. + pdata->is_ar91xx = 1;
  695. + break;
  696. +
  697. + case AR71XX_SOC_AR9132:
  698. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  699. + : ar91xx_ddr_flush_ge0;
  700. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  701. + : ar91xx_set_pll_ge0;
  702. + pdata->is_ar91xx = 1;
  703. + pdata->has_gbit = 1;
  704. + break;
  705. +
  706. + default:
  707. + BUG();
  708. + }
  709. +
  710. + switch (pdata->phy_if_mode) {
  711. + case PHY_INTERFACE_MODE_GMII:
  712. + case PHY_INTERFACE_MODE_RGMII:
  713. + if (!pdata->has_gbit) {
  714. + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
  715. + id);
  716. + return;
  717. + }
  718. + /* fallthrough */
  719. + default:
  720. + break;
  721. + }
  722. +
  723. + if (is_valid_ether_addr(ar71xx_mac_base)) {
  724. + memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
  725. + pdata->mac_addr[5] += ar71xx_eth_instance;
  726. + } else {
  727. + random_ether_addr(pdata->mac_addr);
  728. + printk(KERN_DEBUG
  729. + "ar71xx: using random MAC address for eth%d\n",
  730. + ar71xx_eth_instance);
  731. + }
  732. +
  733. + platform_device_register(pdev);
  734. + ar71xx_eth_instance++;
  735. +}
  736. +
  737. +static struct resource ar71xx_spi_resources[] = {
  738. + [0] = {
  739. + .start = AR71XX_SPI_BASE,
  740. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  741. + .flags = IORESOURCE_MEM,
  742. + },
  743. +};
  744. +
  745. +static struct platform_device ar71xx_spi_device = {
  746. + .name = "ar71xx-spi",
  747. + .id = -1,
  748. + .resource = ar71xx_spi_resources,
  749. + .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
  750. +};
  751. +
  752. +void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  753. + struct spi_board_info const *info,
  754. + unsigned n)
  755. +{
  756. + spi_register_board_info(info, n);
  757. + ar71xx_spi_device.dev.platform_data = pdata;
  758. + platform_device_register(&ar71xx_spi_device);
  759. +}
  760. +
  761. +void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
  762. + struct gpio_led *leds)
  763. +{
  764. + struct platform_device *pdev;
  765. + struct gpio_led_platform_data pdata;
  766. + struct gpio_led *p;
  767. + int err;
  768. +
  769. + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
  770. + if (!p)
  771. + return;
  772. +
  773. + memcpy(p, leds, num_leds * sizeof(*p));
  774. +
  775. + pdev = platform_device_alloc("leds-gpio", id);
  776. + if (!pdev)
  777. + goto err_free_leds;
  778. +
  779. + memset(&pdata, 0, sizeof(pdata));
  780. + pdata.num_leds = num_leds;
  781. + pdata.leds = p;
  782. +
  783. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  784. + if (err)
  785. + goto err_put_pdev;
  786. +
  787. + err = platform_device_add(pdev);
  788. + if (err)
  789. + goto err_put_pdev;
  790. +
  791. + return;
  792. +
  793. +err_put_pdev:
  794. + platform_device_put(pdev);
  795. +
  796. +err_free_leds:
  797. + kfree(p);
  798. +}
  799. +
  800. +void __init ar71xx_add_device_gpio_buttons(int id,
  801. + unsigned poll_interval,
  802. + unsigned nbuttons,
  803. + struct gpio_button *buttons)
  804. +{
  805. + struct platform_device *pdev;
  806. + struct gpio_buttons_platform_data pdata;
  807. + struct gpio_button *p;
  808. + int err;
  809. +
  810. + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
  811. + if (!p)
  812. + return;
  813. +
  814. + memcpy(p, buttons, nbuttons * sizeof(*p));
  815. +
  816. + pdev = platform_device_alloc("gpio-buttons", id);
  817. + if (!pdev)
  818. + goto err_free_buttons;
  819. +
  820. + memset(&pdata, 0, sizeof(pdata));
  821. + pdata.poll_interval = poll_interval;
  822. + pdata.nbuttons = nbuttons;
  823. + pdata.buttons = p;
  824. +
  825. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  826. + if (err)
  827. + goto err_put_pdev;
  828. +
  829. +
  830. + err = platform_device_add(pdev);
  831. + if (err)
  832. + goto err_put_pdev;
  833. +
  834. + return;
  835. +
  836. +err_put_pdev:
  837. + platform_device_put(pdev);
  838. +
  839. +err_free_buttons:
  840. + kfree(p);
  841. +}
  842. +
  843. +void __init ar71xx_add_device_wdt(void)
  844. +{
  845. + platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
  846. +}
  847. +
  848. +void __init ar71xx_set_mac_base(unsigned char *mac)
  849. +{
  850. + memcpy(ar71xx_mac_base, mac, ETH_ALEN);
  851. +}
  852. +
  853. +void __init ar71xx_parse_mac_addr(char *mac_str)
  854. +{
  855. + u8 tmp[ETH_ALEN];
  856. + int t;
  857. +
  858. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  859. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  860. +
  861. + if (t != ETH_ALEN)
  862. + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
  863. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  864. +
  865. + if (t == ETH_ALEN)
  866. + ar71xx_set_mac_base(tmp);
  867. + else
  868. + printk(KERN_DEBUG "ar71xx: failed to parse mac address "
  869. + "\"%s\"\n", mac_str);
  870. +}
  871. +
  872. +static struct resource ar91xx_wmac_resources[] = {
  873. + {
  874. + .start = AR91XX_WMAC_BASE,
  875. + .end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
  876. + .flags = IORESOURCE_MEM,
  877. + }, {
  878. + .start = AR71XX_CPU_IRQ_WMAC,
  879. + .end = AR71XX_CPU_IRQ_WMAC,
  880. + .flags = IORESOURCE_IRQ,
  881. + },
  882. +};
  883. +
  884. +static struct ath9k_platform_data ar91xx_wmac_data;
  885. +
  886. +static struct platform_device ar91xx_wmac_device = {
  887. + .name = "ath9k",
  888. + .id = -1,
  889. + .resource = ar91xx_wmac_resources,
  890. + .num_resources = ARRAY_SIZE(ar91xx_wmac_resources),
  891. + .dev = {
  892. + .platform_data = &ar91xx_wmac_data,
  893. + },
  894. +};
  895. +
  896. +void __init ar91xx_add_device_wmac(void)
  897. +{
  898. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  899. +
  900. + memcpy(ar91xx_wmac_data.eeprom_data, ee,
  901. + sizeof(ar91xx_wmac_data.eeprom_data));
  902. +
  903. + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
  904. + mdelay(10);
  905. +
  906. + ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
  907. + mdelay(10);
  908. +
  909. + platform_device_register(&ar91xx_wmac_device);
  910. +}
  911. +
  912. +static struct platform_device ar71xx_dsa_switch_device = {
  913. + .name = "dsa",
  914. + .id = 0,
  915. +};
  916. +
  917. +void __init ar71xx_add_device_dsa(unsigned int id,
  918. + struct dsa_platform_data *d)
  919. +{
  920. + switch (id) {
  921. + case 0:
  922. + d->netdev = &ar71xx_eth0_device.dev;
  923. + break;
  924. + case 1:
  925. + d->netdev = &ar71xx_eth1_device.dev;
  926. + break;
  927. + default:
  928. + printk(KERN_ERR
  929. + "ar71xx: invalid ethernet id %d for DSA switch\n",
  930. + id);
  931. + return;
  932. + }
  933. + d->mii_bus = &ar71xx_mdio_device.dev;
  934. + ar71xx_dsa_switch_device.dev.platform_data = d;
  935. +
  936. + platform_device_register(&ar71xx_dsa_switch_device);
  937. +}
  938. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/devices.h linux-2.6.29.1/arch/mips/ar71xx/devices.h
  939. --- linux-2.6.29.1.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100
  940. +++ linux-2.6.29.1/arch/mips/ar71xx/devices.h 2009-04-13 14:27:34.491064431 +0200
  941. @@ -0,0 +1,58 @@
  942. +/*
  943. + * Atheros AR71xx SoC device definitions
  944. + *
  945. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  946. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  947. + *
  948. + * This program is free software; you can redistribute it and/or modify it
  949. + * under the terms of the GNU General Public License version 2 as published
  950. + * by the Free Software Foundation.
  951. + */
  952. +
  953. +#ifndef __AR71XX_DEVICES_H
  954. +#define __AR71XX_DEVICES_H
  955. +
  956. +#include <asm/mach-ar71xx/platform.h>
  957. +
  958. +#include <linux/leds.h>
  959. +#include <linux/gpio_buttons.h>
  960. +#include <net/dsa.h>
  961. +
  962. +void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  963. + struct spi_board_info const *info,
  964. + unsigned n) __init;
  965. +
  966. +void ar71xx_set_mac_base(unsigned char *mac) __init;
  967. +void ar71xx_parse_mac_addr(char *mac_str) __init;
  968. +
  969. +extern struct ag71xx_platform_data ar71xx_eth0_data;
  970. +extern struct ag71xx_platform_data ar71xx_eth1_data;
  971. +void ar71xx_add_device_eth(unsigned int id) __init;
  972. +
  973. +void ar71xx_add_device_mdio(u32 phy_mask) __init;
  974. +
  975. +void ar71xx_add_device_leds_gpio(int id,
  976. + unsigned num_leds,
  977. + struct gpio_led *leds) __init;
  978. +
  979. +void ar71xx_add_device_gpio_buttons(int id,
  980. + unsigned poll_interval,
  981. + unsigned nbuttons,
  982. + struct gpio_button *buttons) __init;
  983. +
  984. +void ar71xx_add_device_usb(void) __init;
  985. +
  986. +#ifdef CONFIG_AR71XX_EARLY_SERIAL
  987. +static inline void ar71xx_add_device_uart(void) {}
  988. +#else
  989. +void ar71xx_add_device_uart(void) __init;
  990. +#endif
  991. +
  992. +void ar71xx_add_device_wdt(void) __init;
  993. +
  994. +void ar91xx_add_device_wmac(void) __init;
  995. +
  996. +void ar71xx_add_device_dsa(unsigned int id,
  997. + struct dsa_platform_data *d) __init;
  998. +
  999. +#endif /* __AR71XX_DEVICES_H */
  1000. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/gpio.c linux-2.6.29.1/arch/mips/ar71xx/gpio.c
  1001. --- linux-2.6.29.1.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
  1002. +++ linux-2.6.29.1/arch/mips/ar71xx/gpio.c 2009-04-13 14:27:34.495064103 +0200
  1003. @@ -0,0 +1,154 @@
  1004. +/*
  1005. + * Atheros AR71xx SoC GPIO API support
  1006. + *
  1007. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  1008. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1009. + *
  1010. + * This program is free software; you can redistribute it and/or modify it
  1011. + * under the terms of the GNU General Public License version 2 as published
  1012. + * by the Free Software Foundation.
  1013. + */
  1014. +
  1015. +#include <linux/kernel.h>
  1016. +#include <linux/init.h>
  1017. +#include <linux/module.h>
  1018. +#include <linux/types.h>
  1019. +#include <linux/spinlock.h>
  1020. +#include <linux/io.h>
  1021. +#include <linux/ioport.h>
  1022. +#include <linux/gpio.h>
  1023. +
  1024. +#include <asm/mach-ar71xx/ar71xx.h>
  1025. +
  1026. +static DEFINE_SPINLOCK(ar71xx_gpio_lock);
  1027. +
  1028. +unsigned long ar71xx_gpio_count;
  1029. +EXPORT_SYMBOL(ar71xx_gpio_count);
  1030. +
  1031. +void __ar71xx_gpio_set_value(unsigned gpio, int value)
  1032. +{
  1033. + unsigned long flags;
  1034. +
  1035. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  1036. +
  1037. + if (value)
  1038. + ar71xx_gpio_wr(GPIO_REG_SET, (1 << gpio));
  1039. + else
  1040. + ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << gpio));
  1041. +
  1042. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  1043. +}
  1044. +EXPORT_SYMBOL(__ar71xx_gpio_set_value);
  1045. +
  1046. +int __ar71xx_gpio_get_value(unsigned gpio)
  1047. +{
  1048. + return (ar71xx_gpio_rr(GPIO_REG_IN) & (1 << gpio)) ? 1 : 0;
  1049. +}
  1050. +EXPORT_SYMBOL(__ar71xx_gpio_get_value);
  1051. +
  1052. +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  1053. +{
  1054. + return __ar71xx_gpio_get_value(offset);
  1055. +}
  1056. +
  1057. +static void ar71xx_gpio_set_value(struct gpio_chip *chip,
  1058. + unsigned offset, int value)
  1059. +{
  1060. + __ar71xx_gpio_set_value(offset, value);
  1061. +}
  1062. +
  1063. +static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
  1064. + unsigned offset)
  1065. +{
  1066. + unsigned long flags;
  1067. +
  1068. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  1069. +
  1070. + ar71xx_gpio_wr(GPIO_REG_OE,
  1071. + ar71xx_gpio_rr(GPIO_REG_OE) & ~(1 << offset));
  1072. +
  1073. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  1074. +
  1075. + return 0;
  1076. +}
  1077. +
  1078. +static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
  1079. + unsigned offset, int value)
  1080. +{
  1081. + unsigned long flags;
  1082. +
  1083. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  1084. +
  1085. + if (value)
  1086. + ar71xx_gpio_wr(GPIO_REG_SET, (1 << offset));
  1087. + else
  1088. + ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << offset));
  1089. +
  1090. + ar71xx_gpio_wr(GPIO_REG_OE,
  1091. + ar71xx_gpio_rr(GPIO_REG_OE) | (1 << offset));
  1092. +
  1093. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  1094. +
  1095. + return 0;
  1096. +}
  1097. +
  1098. +static struct gpio_chip ar71xx_gpio_chip = {
  1099. + .label = "ar71xx",
  1100. + .get = ar71xx_gpio_get_value,
  1101. + .set = ar71xx_gpio_set_value,
  1102. + .direction_input = ar71xx_gpio_direction_input,
  1103. + .direction_output = ar71xx_gpio_direction_output,
  1104. + .base = 0,
  1105. + .ngpio = AR71XX_GPIO_COUNT,
  1106. +};
  1107. +
  1108. +void ar71xx_gpio_function_enable(u32 mask)
  1109. +{
  1110. + unsigned long flags;
  1111. +
  1112. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  1113. +
  1114. + ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) | mask);
  1115. +
  1116. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  1117. +}
  1118. +
  1119. +void ar71xx_gpio_function_disable(u32 mask)
  1120. +{
  1121. + unsigned long flags;
  1122. +
  1123. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  1124. +
  1125. + ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) & ~mask);
  1126. +
  1127. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  1128. +}
  1129. +
  1130. +void __init ar71xx_gpio_init(void)
  1131. +{
  1132. + int err;
  1133. +
  1134. + if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
  1135. + "AR71xx GPIO controller"))
  1136. + panic("cannot allocate AR71xx GPIO registers page");
  1137. +
  1138. + switch (ar71xx_soc) {
  1139. + case AR71XX_SOC_AR7130:
  1140. + case AR71XX_SOC_AR7141:
  1141. + case AR71XX_SOC_AR7161:
  1142. + ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
  1143. + break;
  1144. +
  1145. + case AR71XX_SOC_AR9130:
  1146. + case AR71XX_SOC_AR9132:
  1147. + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
  1148. + break;
  1149. +
  1150. + default:
  1151. + BUG();
  1152. + }
  1153. +
  1154. + err = gpiochip_add(&ar71xx_gpio_chip);
  1155. + if (err)
  1156. + panic("cannot add AR71xx GPIO chip, error=%d", err);
  1157. +}
  1158. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/irq.c linux-2.6.29.1/arch/mips/ar71xx/irq.c
  1159. --- linux-2.6.29.1.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100
  1160. +++ linux-2.6.29.1/arch/mips/ar71xx/irq.c 2009-04-13 14:27:34.543070220 +0200
  1161. @@ -0,0 +1,302 @@
  1162. +/*
  1163. + * Atheros AR71xx SoC specific interrupt handling
  1164. + *
  1165. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  1166. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1167. + *
  1168. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1169. + *
  1170. + * This program is free software; you can redistribute it and/or modify it
  1171. + * under the terms of the GNU General Public License version 2 as published
  1172. + * by the Free Software Foundation.
  1173. + */
  1174. +
  1175. +#include <linux/kernel.h>
  1176. +#include <linux/init.h>
  1177. +#include <linux/interrupt.h>
  1178. +#include <linux/irq.h>
  1179. +
  1180. +#include <asm/irq_cpu.h>
  1181. +#include <asm/mipsregs.h>
  1182. +
  1183. +#include <asm/mach-ar71xx/ar71xx.h>
  1184. +
  1185. +#ifdef CONFIG_PCI
  1186. +static void ar71xx_pci_irq_dispatch(void)
  1187. +{
  1188. + u32 pending;
  1189. +
  1190. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_STATUS) &
  1191. + ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE);
  1192. +
  1193. + if (pending & PCI_INT_DEV0)
  1194. + do_IRQ(AR71XX_PCI_IRQ_DEV0);
  1195. +
  1196. + else if (pending & PCI_INT_DEV1)
  1197. + do_IRQ(AR71XX_PCI_IRQ_DEV1);
  1198. +
  1199. + else if (pending & PCI_INT_DEV2)
  1200. + do_IRQ(AR71XX_PCI_IRQ_DEV2);
  1201. +
  1202. + else
  1203. + spurious_interrupt();
  1204. +}
  1205. +
  1206. +static void ar71xx_pci_irq_unmask(unsigned int irq)
  1207. +{
  1208. + irq -= AR71XX_PCI_IRQ_BASE;
  1209. + ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE,
  1210. + ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE) | (1 << irq));
  1211. +}
  1212. +
  1213. +static void ar71xx_pci_irq_mask(unsigned int irq)
  1214. +{
  1215. + irq -= AR71XX_PCI_IRQ_BASE;
  1216. + ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE,
  1217. + ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE) & ~(1 << irq));
  1218. +}
  1219. +
  1220. +static struct irq_chip ar71xx_pci_irq_chip = {
  1221. + .name = "AR71XX PCI ",
  1222. + .mask = ar71xx_pci_irq_mask,
  1223. + .unmask = ar71xx_pci_irq_unmask,
  1224. + .mask_ack = ar71xx_pci_irq_mask,
  1225. +};
  1226. +
  1227. +static struct irqaction ar71xx_pci_irqaction = {
  1228. + .handler = no_action,
  1229. + .name = "cascade [AR71XX PCI]",
  1230. +};
  1231. +
  1232. +static void __init ar71xx_pci_irq_init(void)
  1233. +{
  1234. + int i;
  1235. +
  1236. + ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE, 0);
  1237. + ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_STATUS, 0);
  1238. +
  1239. + for (i = AR71XX_PCI_IRQ_BASE;
  1240. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  1241. + irq_desc[i].status = IRQ_DISABLED;
  1242. + set_irq_chip_and_handler(i, &ar71xx_pci_irq_chip,
  1243. + handle_level_irq);
  1244. + }
  1245. +
  1246. + setup_irq(AR71XX_CPU_IRQ_PCI, &ar71xx_pci_irqaction);
  1247. +}
  1248. +#endif /* CONFIG_PCI */
  1249. +
  1250. +static void ar71xx_gpio_irq_dispatch(void)
  1251. +{
  1252. + u32 pending;
  1253. +
  1254. + pending = ar71xx_gpio_rr(GPIO_REG_INT_PENDING)
  1255. + & ar71xx_gpio_rr(GPIO_REG_INT_ENABLE);
  1256. +
  1257. + if (pending)
  1258. + do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
  1259. + else
  1260. + spurious_interrupt();
  1261. +}
  1262. +
  1263. +static void ar71xx_gpio_irq_unmask(unsigned int irq)
  1264. +{
  1265. + irq -= AR71XX_GPIO_IRQ_BASE;
  1266. + ar71xx_gpio_wr(GPIO_REG_INT_ENABLE,
  1267. + ar71xx_gpio_rr(GPIO_REG_INT_ENABLE) | (1 << irq));
  1268. +}
  1269. +
  1270. +static void ar71xx_gpio_irq_mask(unsigned int irq)
  1271. +{
  1272. + irq -= AR71XX_GPIO_IRQ_BASE;
  1273. + ar71xx_gpio_wr(GPIO_REG_INT_ENABLE,
  1274. + ar71xx_gpio_rr(GPIO_REG_INT_ENABLE) & ~(1 << irq));
  1275. +}
  1276. +
  1277. +#if 0
  1278. +static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
  1279. +{
  1280. + /* TODO: implement */
  1281. + return 0;
  1282. +}
  1283. +#else
  1284. +#define ar71xx_gpio_irq_set_type NULL
  1285. +#endif
  1286. +
  1287. +struct irq_chip ar71xx_gpio_irq_chip = {
  1288. + .name = "AR71XX GPIO",
  1289. + .unmask = ar71xx_gpio_irq_unmask,
  1290. + .mask = ar71xx_gpio_irq_mask,
  1291. + .mask_ack = ar71xx_gpio_irq_mask,
  1292. + .set_type = ar71xx_gpio_irq_set_type,
  1293. +};
  1294. +
  1295. +static struct irqaction ar71xx_gpio_irqaction = {
  1296. + .handler = no_action,
  1297. + .name = "cascade [AR71XX GPIO]",
  1298. +};
  1299. +
  1300. +#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED)
  1301. +#define GPIO_INT_ALL 0xffff
  1302. +
  1303. +static void __init ar71xx_gpio_irq_init(void)
  1304. +{
  1305. + int i;
  1306. +
  1307. + ar71xx_gpio_wr(GPIO_REG_INT_ENABLE, 0);
  1308. + ar71xx_gpio_wr(GPIO_REG_INT_PENDING, 0);
  1309. +
  1310. + /* setup type of all GPIO interrupts to level sensitive */
  1311. + ar71xx_gpio_wr(GPIO_REG_INT_TYPE, GPIO_INT_ALL);
  1312. +
  1313. + /* setup polarity of all GPIO interrupts to active high */
  1314. + ar71xx_gpio_wr(GPIO_REG_INT_POLARITY, GPIO_INT_ALL);
  1315. +
  1316. + for (i = AR71XX_GPIO_IRQ_BASE;
  1317. + i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) {
  1318. + irq_desc[i].status = GPIO_IRQ_INIT_STATUS;
  1319. + set_irq_chip_and_handler(i, &ar71xx_gpio_irq_chip,
  1320. + handle_level_irq);
  1321. + }
  1322. +
  1323. + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
  1324. +}
  1325. +
  1326. +static void ar71xx_misc_irq_dispatch(void)
  1327. +{
  1328. + u32 pending;
  1329. +
  1330. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
  1331. + & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
  1332. +
  1333. + if (pending & MISC_INT_UART)
  1334. + do_IRQ(AR71XX_MISC_IRQ_UART);
  1335. +
  1336. + else if (pending & MISC_INT_DMA)
  1337. + do_IRQ(AR71XX_MISC_IRQ_DMA);
  1338. +
  1339. + else if (pending & MISC_INT_PERFC)
  1340. + do_IRQ(AR71XX_MISC_IRQ_PERFC);
  1341. +
  1342. + else if (pending & MISC_INT_TIMER)
  1343. + do_IRQ(AR71XX_MISC_IRQ_TIMER);
  1344. +
  1345. + else if (pending & MISC_INT_OHCI)
  1346. + do_IRQ(AR71XX_MISC_IRQ_OHCI);
  1347. +
  1348. + else if (pending & MISC_INT_ERROR)
  1349. + do_IRQ(AR71XX_MISC_IRQ_ERROR);
  1350. +
  1351. + else if (pending & MISC_INT_GPIO)
  1352. + ar71xx_gpio_irq_dispatch();
  1353. +
  1354. + else if (pending & MISC_INT_WDOG)
  1355. + do_IRQ(AR71XX_MISC_IRQ_WDOG);
  1356. +
  1357. + else
  1358. + spurious_interrupt();
  1359. +}
  1360. +
  1361. +static void ar71xx_misc_irq_unmask(unsigned int irq)
  1362. +{
  1363. + irq -= AR71XX_MISC_IRQ_BASE;
  1364. + ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE,
  1365. + ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE) | (1 << irq));
  1366. +}
  1367. +
  1368. +static void ar71xx_misc_irq_mask(unsigned int irq)
  1369. +{
  1370. + irq -= AR71XX_MISC_IRQ_BASE;
  1371. + ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE,
  1372. + ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE) & ~(1 << irq));
  1373. +}
  1374. +
  1375. +struct irq_chip ar71xx_misc_irq_chip = {
  1376. + .name = "AR71XX MISC",
  1377. + .unmask = ar71xx_misc_irq_unmask,
  1378. + .mask = ar71xx_misc_irq_mask,
  1379. + .mask_ack = ar71xx_misc_irq_mask,
  1380. +};
  1381. +
  1382. +static struct irqaction ar71xx_misc_irqaction = {
  1383. + .handler = no_action,
  1384. + .name = "cascade [AR71XX MISC]",
  1385. +};
  1386. +
  1387. +static void __init ar71xx_misc_irq_init(void)
  1388. +{
  1389. + int i;
  1390. +
  1391. + ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, 0);
  1392. + ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_STATUS, 0);
  1393. +
  1394. + for (i = AR71XX_MISC_IRQ_BASE;
  1395. + i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) {
  1396. + irq_desc[i].status = IRQ_DISABLED;
  1397. + set_irq_chip_and_handler(i, &ar71xx_misc_irq_chip,
  1398. + handle_level_irq);
  1399. + }
  1400. +
  1401. + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
  1402. +}
  1403. +
  1404. +static void ar913x_wmac_irq_dispatch(void)
  1405. +{
  1406. + do_IRQ(AR71XX_CPU_IRQ_WMAC);
  1407. +}
  1408. +
  1409. +static void (* ar71xx_ip2_irq_handler)(void) = spurious_interrupt;
  1410. +
  1411. +asmlinkage void plat_irq_dispatch(void)
  1412. +{
  1413. + unsigned long pending;
  1414. +
  1415. + pending = read_c0_status() & read_c0_cause() & ST0_IM;
  1416. +
  1417. + if (pending & STATUSF_IP7)
  1418. + do_IRQ(AR71XX_CPU_IRQ_TIMER);
  1419. +
  1420. + else if (pending & STATUSF_IP2)
  1421. + ar71xx_ip2_irq_handler();
  1422. +
  1423. + else if (pending & STATUSF_IP4)
  1424. + do_IRQ(AR71XX_CPU_IRQ_GE0);
  1425. +
  1426. + else if (pending & STATUSF_IP5)
  1427. + do_IRQ(AR71XX_CPU_IRQ_GE1);
  1428. +
  1429. + else if (pending & STATUSF_IP3)
  1430. + do_IRQ(AR71XX_CPU_IRQ_USB);
  1431. +
  1432. + else if (pending & STATUSF_IP6)
  1433. + ar71xx_misc_irq_dispatch();
  1434. +
  1435. + else
  1436. + spurious_interrupt();
  1437. +}
  1438. +
  1439. +void __init arch_init_irq(void)
  1440. +{
  1441. + mips_cpu_irq_init();
  1442. +
  1443. + ar71xx_misc_irq_init();
  1444. +
  1445. + switch (ar71xx_soc) {
  1446. + case AR71XX_SOC_AR7130:
  1447. + case AR71XX_SOC_AR7141:
  1448. + case AR71XX_SOC_AR7161:
  1449. +#ifdef CONFIG_PCI
  1450. + ar71xx_pci_irq_init();
  1451. + ar71xx_ip2_irq_handler = ar71xx_pci_irq_dispatch;
  1452. +#endif
  1453. + break;
  1454. + case AR71XX_SOC_AR9130:
  1455. + case AR71XX_SOC_AR9132:
  1456. + ar71xx_ip2_irq_handler = ar913x_wmac_irq_dispatch;
  1457. + break;
  1458. + default:
  1459. + BUG();
  1460. + }
  1461. +
  1462. + ar71xx_gpio_irq_init();
  1463. +}
  1464. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.29.1/arch/mips/ar71xx/mach-ap81.c
  1465. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100
  1466. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-ap81.c 2009-04-13 14:27:34.543070220 +0200
  1467. @@ -0,0 +1,148 @@
  1468. +/*
  1469. + * Atheros AP81 board support
  1470. + *
  1471. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1472. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  1473. + *
  1474. + * This program is free software; you can redistribute it and/or modify it
  1475. + * under the terms of the GNU General Public License version 2 as published
  1476. + * by the Free Software Foundation.
  1477. + */
  1478. +
  1479. +#include <linux/platform_device.h>
  1480. +#include <linux/mtd/mtd.h>
  1481. +#include <linux/mtd/partitions.h>
  1482. +#include <linux/spi/spi.h>
  1483. +#include <linux/spi/flash.h>
  1484. +#include <linux/input.h>
  1485. +
  1486. +#include <asm/mips_machine.h>
  1487. +#include <asm/mach-ar71xx/ar71xx.h>
  1488. +
  1489. +#include "devices.h"
  1490. +
  1491. +#define AP81_GPIO_LED_STATUS 1
  1492. +#define AP81_GPIO_LED_AOSS 3
  1493. +#define AP81_GPIO_LED_WLAN 6
  1494. +#define AP81_GPIO_LED_POWER 14
  1495. +
  1496. +#define AP81_GPIO_BTN_SW4 12
  1497. +#define AP81_GPIO_BTN_SW1 21
  1498. +
  1499. +#define AP81_BUTTONS_POLL_INTERVAL 20
  1500. +
  1501. +#ifdef CONFIG_MTD_PARTITIONS
  1502. +static struct mtd_partition ap81_partitions[] = {
  1503. + {
  1504. + .name = "u-boot",
  1505. + .offset = 0,
  1506. + .size = 0x040000,
  1507. + .mask_flags = MTD_WRITEABLE,
  1508. + } , {
  1509. + .name = "u-boot-env",
  1510. + .offset = 0x040000,
  1511. + .size = 0x010000,
  1512. + } , {
  1513. + .name = "rootfs",
  1514. + .offset = 0x050000,
  1515. + .size = 0x500000,
  1516. + } , {
  1517. + .name = "uImage",
  1518. + .offset = 0x550000,
  1519. + .size = 0x100000,
  1520. + } , {
  1521. + .name = "ART",
  1522. + .offset = 0x650000,
  1523. + .size = 0x1b0000,
  1524. + .mask_flags = MTD_WRITEABLE,
  1525. + }
  1526. +};
  1527. +#endif /* CONFIG_MTD_PARTITIONS */
  1528. +
  1529. +static struct flash_platform_data ap81_flash_data = {
  1530. +#ifdef CONFIG_MTD_PARTITIONS
  1531. + .parts = ap81_partitions,
  1532. + .nr_parts = ARRAY_SIZE(ap81_partitions),
  1533. +#endif
  1534. +};
  1535. +
  1536. +static struct spi_board_info ap81_spi_info[] = {
  1537. + {
  1538. + .bus_num = 0,
  1539. + .chip_select = 0,
  1540. + .max_speed_hz = 25000000,
  1541. + .modalias = "m25p80",
  1542. + .platform_data = &ap81_flash_data,
  1543. + }
  1544. +};
  1545. +
  1546. +static struct gpio_led ap81_leds_gpio[] __initdata = {
  1547. + {
  1548. + .name = "ap81:green:status",
  1549. + .gpio = AP81_GPIO_LED_STATUS,
  1550. + .active_low = 1,
  1551. + }, {
  1552. + .name = "ap81:amber:aoss",
  1553. + .gpio = AP81_GPIO_LED_AOSS,
  1554. + .active_low = 1,
  1555. + }, {
  1556. + .name = "ap81:green:wlan",
  1557. + .gpio = AP81_GPIO_LED_WLAN,
  1558. + .active_low = 1,
  1559. + }, {
  1560. + .name = "ap81:green:power",
  1561. + .gpio = AP81_GPIO_LED_POWER,
  1562. + .active_low = 1,
  1563. + }
  1564. +};
  1565. +
  1566. +static struct gpio_button ap81_gpio_buttons[] __initdata = {
  1567. + {
  1568. + .desc = "sw1",
  1569. + .type = EV_KEY,
  1570. + .code = BTN_0,
  1571. + .threshold = 5,
  1572. + .gpio = AP81_GPIO_BTN_SW1,
  1573. + .active_low = 1,
  1574. + } , {
  1575. + .desc = "sw4",
  1576. + .type = EV_KEY,
  1577. + .code = BTN_1,
  1578. + .threshold = 5,
  1579. + .gpio = AP81_GPIO_BTN_SW4,
  1580. + .active_low = 1,
  1581. + }
  1582. +};
  1583. +
  1584. +static void __init ap81_setup(void)
  1585. +{
  1586. + ar71xx_add_device_mdio(0x0);
  1587. +
  1588. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  1589. + ar71xx_eth0_data.phy_mask = 0xf;
  1590. + ar71xx_eth0_data.speed = SPEED_100;
  1591. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  1592. + ar71xx_eth0_data.has_ar8216 = 1;
  1593. +
  1594. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  1595. + ar71xx_eth1_data.phy_mask = 0x10;
  1596. +
  1597. + ar71xx_add_device_eth(0);
  1598. + ar71xx_add_device_eth(1);
  1599. +
  1600. + ar71xx_add_device_usb();
  1601. +
  1602. + ar71xx_add_device_spi(NULL, ap81_spi_info,
  1603. + ARRAY_SIZE(ap81_spi_info));
  1604. +
  1605. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
  1606. + ap81_leds_gpio);
  1607. +
  1608. + ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL,
  1609. + ARRAY_SIZE(ap81_gpio_buttons),
  1610. + ap81_gpio_buttons);
  1611. +
  1612. + ar91xx_add_device_wmac();
  1613. +}
  1614. +
  1615. +MIPS_MACHINE(AR71XX_MACH_AP81, "Atheros AP81", ap81_setup);
  1616. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.29.1/arch/mips/ar71xx/mach-ap83.c
  1617. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100
  1618. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-ap83.c 2009-04-13 14:27:34.547067937 +0200
  1619. @@ -0,0 +1,87 @@
  1620. +/*
  1621. + * Atheros AP83 board support
  1622. + *
  1623. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1624. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1625. + *
  1626. + * This program is free software; you can redistribute it and/or modify it
  1627. + * under the terms of the GNU General Public License version 2 as published
  1628. + * by the Free Software Foundation.
  1629. + */
  1630. +
  1631. +#include <linux/platform_device.h>
  1632. +#include <linux/input.h>
  1633. +
  1634. +#include <asm/mips_machine.h>
  1635. +#include <asm/mach-ar71xx/ar71xx.h>
  1636. +
  1637. +#include "devices.h"
  1638. +
  1639. +#define AP83_GPIO_LED_WLAN 6
  1640. +#define AP83_GPIO_LED_POWER 14
  1641. +#define AP83_GPIO_LED_JUMPSTART 15
  1642. +#define AP83_GPIO_BTN_JUMPSTART 12
  1643. +#define AP83_GPIO_BTN_RESET 21
  1644. +
  1645. +static struct gpio_led ap83_leds_gpio[] __initdata = {
  1646. + {
  1647. + .name = "ap83:green:jumpstart",
  1648. + .gpio = AP83_GPIO_LED_JUMPSTART,
  1649. + .active_low = 0,
  1650. + }, {
  1651. + .name = "ap83:green:power",
  1652. + .gpio = AP83_GPIO_LED_POWER,
  1653. + .active_low = 0,
  1654. + }, {
  1655. + .name = "ap83:green:wlan",
  1656. + .gpio = AP83_GPIO_LED_WLAN,
  1657. + .active_low = 0,
  1658. + },
  1659. +};
  1660. +
  1661. +static struct gpio_button ap83_gpio_buttons[] __initdata = {
  1662. + {
  1663. + .desc = "soft_reset",
  1664. + .type = EV_KEY,
  1665. + .code = BTN_0,
  1666. + .threshold = 5,
  1667. + .gpio = AP83_GPIO_BTN_RESET,
  1668. + .active_low = 1,
  1669. + } , {
  1670. + .desc = "jumpstart",
  1671. + .type = EV_KEY,
  1672. + .code = BTN_1,
  1673. + .threshold = 5,
  1674. + .gpio = AP83_GPIO_BTN_JUMPSTART,
  1675. + .active_low = 1,
  1676. + }
  1677. +};
  1678. +
  1679. +static void __init ap83_setup(void)
  1680. +{
  1681. + ar71xx_add_device_mdio(0xfffffffe);
  1682. +
  1683. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  1684. + ar71xx_eth0_data.phy_mask = 0x1;
  1685. +
  1686. + ar71xx_add_device_eth(0);
  1687. +
  1688. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  1689. + ar71xx_eth1_data.phy_mask = 0x0;
  1690. + ar71xx_eth1_data.speed = SPEED_1000;
  1691. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  1692. +
  1693. + ar71xx_add_device_eth(1);
  1694. +
  1695. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
  1696. + ap83_leds_gpio);
  1697. +
  1698. + ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(ap83_gpio_buttons),
  1699. + ap83_gpio_buttons);
  1700. +
  1701. + ar71xx_add_device_usb();
  1702. +
  1703. + ar91xx_add_device_wmac();
  1704. +}
  1705. +
  1706. +MIPS_MACHINE(AR71XX_MACH_AP83, "Atheros AP83", ap83_setup);
  1707. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.29.1/arch/mips/ar71xx/mach-aw-nr580.c
  1708. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100
  1709. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-aw-nr580.c 2009-04-13 14:27:34.547067937 +0200
  1710. @@ -0,0 +1,119 @@
  1711. +/*
  1712. + * AzureWave AW-NR580 board support
  1713. + *
  1714. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1715. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1716. + *
  1717. + * This program is free software; you can redistribute it and/or modify it
  1718. + * under the terms of the GNU General Public License version 2 as published
  1719. + * by the Free Software Foundation.
  1720. + */
  1721. +
  1722. +#include <linux/platform_device.h>
  1723. +#include <linux/mtd/mtd.h>
  1724. +#include <linux/mtd/partitions.h>
  1725. +#include <linux/spi/spi.h>
  1726. +#include <linux/spi/flash.h>
  1727. +#include <linux/input.h>
  1728. +
  1729. +#include <asm/mips_machine.h>
  1730. +#include <asm/mach-ar71xx/ar71xx.h>
  1731. +#include <asm/mach-ar71xx/pci.h>
  1732. +
  1733. +#include "devices.h"
  1734. +
  1735. +#define AW_NR580_GPIO_LED_READY_RED 0
  1736. +#define AW_NR580_GPIO_LED_WLAN 1
  1737. +#define AW_NR580_GPIO_LED_READY_GREEN 2
  1738. +#define AW_NR580_GPIO_LED_WPS_GREEN 4
  1739. +#define AW_NR580_GPIO_LED_WPS_AMBER 5
  1740. +
  1741. +#define AW_NR580_GPIO_BTN_WPS 3
  1742. +#define AW_NR580_GPIO_BTN_RESET 11
  1743. +
  1744. +#define AW_NR580_BUTTONS_POLL_INTERVAL 20
  1745. +
  1746. +static struct spi_board_info aw_nr580_spi_info[] = {
  1747. + {
  1748. + .bus_num = 0,
  1749. + .chip_select = 0,
  1750. + .max_speed_hz = 25000000,
  1751. + .modalias = "m25p80",
  1752. + }
  1753. +};
  1754. +
  1755. +static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
  1756. + {
  1757. + .name = "aw-nr580:red:ready",
  1758. + .gpio = AW_NR580_GPIO_LED_READY_RED,
  1759. + .active_low = 0,
  1760. + }, {
  1761. + .name = "aw-nr580:green:ready",
  1762. + .gpio = AW_NR580_GPIO_LED_READY_GREEN,
  1763. + .active_low = 0,
  1764. + }, {
  1765. + .name = "aw-nr580:green:wps",
  1766. + .gpio = AW_NR580_GPIO_LED_WPS_GREEN,
  1767. + .active_low = 0,
  1768. + }, {
  1769. + .name = "aw-nr580:amber:wps",
  1770. + .gpio = AW_NR580_GPIO_LED_WPS_AMBER,
  1771. + .active_low = 0,
  1772. + }, {
  1773. + .name = "aw-nr580:green:wlan",
  1774. + .gpio = AW_NR580_GPIO_LED_WLAN,
  1775. + .active_low = 0,
  1776. + }
  1777. +};
  1778. +
  1779. +static struct gpio_button aw_nr580_gpio_buttons[] __initdata = {
  1780. + {
  1781. + .desc = "reset",
  1782. + .type = EV_KEY,
  1783. + .code = BTN_0,
  1784. + .threshold = 5,
  1785. + .gpio = AW_NR580_GPIO_BTN_RESET,
  1786. + .active_low = 1,
  1787. + }, {
  1788. + .desc = "wps",
  1789. + .type = EV_KEY,
  1790. + .code = BTN_1,
  1791. + .threshold = 5,
  1792. + .gpio = AW_NR580_GPIO_BTN_WPS,
  1793. + .active_low = 1,
  1794. + }
  1795. +};
  1796. +
  1797. +static struct ar71xx_pci_irq aw_nr580_pci_irqs[] __initdata = {
  1798. + {
  1799. + .slot = 1,
  1800. + .pin = 1,
  1801. + .irq = AR71XX_PCI_IRQ_DEV1,
  1802. + }
  1803. +};
  1804. +
  1805. +static void __init aw_nr580_setup(void)
  1806. +{
  1807. + ar71xx_add_device_mdio(0x0);
  1808. +
  1809. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  1810. + ar71xx_eth0_data.phy_mask = 0xf;
  1811. + ar71xx_eth0_data.speed = SPEED_100;
  1812. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  1813. +
  1814. + ar71xx_add_device_eth(0);
  1815. +
  1816. + ar71xx_pci_init(ARRAY_SIZE(aw_nr580_pci_irqs), aw_nr580_pci_irqs);
  1817. +
  1818. + ar71xx_add_device_spi(NULL, aw_nr580_spi_info,
  1819. + ARRAY_SIZE(aw_nr580_spi_info));
  1820. +
  1821. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
  1822. + aw_nr580_leds_gpio);
  1823. +
  1824. + ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL,
  1825. + ARRAY_SIZE(aw_nr580_gpio_buttons),
  1826. + aw_nr580_gpio_buttons);
  1827. +}
  1828. +
  1829. +MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AzureWave AW-NR580", aw_nr580_setup);
  1830. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-generic.c linux-2.6.29.1/arch/mips/ar71xx/mach-generic.c
  1831. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-generic.c 1970-01-01 01:00:00.000000000 +0100
  1832. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-generic.c 2009-04-13 14:27:34.547067937 +0200
  1833. @@ -0,0 +1,22 @@
  1834. +/*
  1835. + * Generic AR71xx machine support
  1836. + *
  1837. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  1838. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1839. + *
  1840. + * This program is free software; you can redistribute it and/or modify it
  1841. + * under the terms of the GNU General Public License version 2 as published
  1842. + * by the Free Software Foundation.
  1843. + */
  1844. +
  1845. +#include <linux/init.h>
  1846. +
  1847. +#include <asm/mips_machine.h>
  1848. +#include <asm/mach-ar71xx/ar71xx.h>
  1849. +
  1850. +static void __init ar71xx_generic_init(void)
  1851. +{
  1852. + /* Nothing to do */
  1853. +}
  1854. +
  1855. +MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic AR71xx board", ar71xx_generic_init);
  1856. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w04nu.c
  1857. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100
  1858. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w04nu.c 2009-04-13 14:27:34.551067888 +0200
  1859. @@ -0,0 +1,173 @@
  1860. +/*
  1861. + * Planex MZK-W04NU board support
  1862. + *
  1863. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1864. + *
  1865. + * This program is free software; you can redistribute it and/or modify it
  1866. + * under the terms of the GNU General Public License version 2 as published
  1867. + * by the Free Software Foundation.
  1868. + */
  1869. +
  1870. +#include <linux/platform_device.h>
  1871. +#include <linux/mtd/mtd.h>
  1872. +#include <linux/mtd/partitions.h>
  1873. +#include <linux/spi/spi.h>
  1874. +#include <linux/spi/flash.h>
  1875. +#include <linux/input.h>
  1876. +
  1877. +#include <asm/mips_machine.h>
  1878. +
  1879. +#include <asm/mach-ar71xx/ar71xx.h>
  1880. +
  1881. +#include "devices.h"
  1882. +
  1883. +#define MZK_W04NU_GPIO_LED_USB 0
  1884. +#define MZK_W04NU_GPIO_LED_STATUS 1
  1885. +#define MZK_W04NU_GPIO_LED_WPS 3
  1886. +#define MZK_W04NU_GPIO_LED_WLAN 6
  1887. +#define MZK_W04NU_GPIO_LED_AP 15
  1888. +#define MZK_W04NU_GPIO_LED_ROUTER 16
  1889. +
  1890. +#define MZK_W04NU_GPIO_BTN_APROUTER 5
  1891. +#define MZK_W04NU_GPIO_BTN_WPS 12
  1892. +#define MZK_W04NU_GPIO_BTN_RESET 21
  1893. +
  1894. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  1895. +
  1896. +#ifdef CONFIG_MTD_PARTITIONS
  1897. +static struct mtd_partition mzk_w04nu_partitions[] = {
  1898. + {
  1899. + .name = "u-boot",
  1900. + .offset = 0,
  1901. + .size = 0x040000,
  1902. + .mask_flags = MTD_WRITEABLE,
  1903. + } , {
  1904. + .name = "u-boot-env",
  1905. + .offset = 0x040000,
  1906. + .size = 0x010000,
  1907. + } , {
  1908. + .name = "kernel",
  1909. + .offset = 0x050000,
  1910. + .size = 0x160000,
  1911. + } , {
  1912. + .name = "rootfs",
  1913. + .offset = 0x1b0000,
  1914. + .size = 0x630000,
  1915. + } , {
  1916. + .name = "art",
  1917. + .offset = 0x7e0000,
  1918. + .size = 0x020000,
  1919. + .mask_flags = MTD_WRITEABLE,
  1920. + } , {
  1921. + .name = "firmware",
  1922. + .offset = 0x050000,
  1923. + .size = 0x770000,
  1924. + }
  1925. +};
  1926. +#endif /* CONFIG_MTD_PARTITIONS */
  1927. +
  1928. +static struct flash_platform_data mzk_w04nu_flash_data = {
  1929. +#ifdef CONFIG_MTD_PARTITIONS
  1930. + .parts = mzk_w04nu_partitions,
  1931. + .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions),
  1932. +#endif
  1933. +};
  1934. +
  1935. +static struct spi_board_info mzk_w04nu_spi_info[] = {
  1936. + {
  1937. + .bus_num = 0,
  1938. + .chip_select = 0,
  1939. + .max_speed_hz = 25000000,
  1940. + .modalias = "m25p80",
  1941. + .platform_data = &mzk_w04nu_flash_data,
  1942. + }
  1943. +};
  1944. +
  1945. +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
  1946. + {
  1947. + .name = "mzk-w04nu:green:status",
  1948. + .gpio = MZK_W04NU_GPIO_LED_STATUS,
  1949. + .active_low = 1,
  1950. + }, {
  1951. + .name = "mzk-w04nu:blue:wps",
  1952. + .gpio = MZK_W04NU_GPIO_LED_WPS,
  1953. + .active_low = 1,
  1954. + }, {
  1955. + .name = "mzk-w04nu:green:wlan",
  1956. + .gpio = MZK_W04NU_GPIO_LED_WLAN,
  1957. + .active_low = 1,
  1958. + }, {
  1959. + .name = "mzk-w04nu:green:usb",
  1960. + .gpio = MZK_W04NU_GPIO_LED_USB,
  1961. + .active_low = 1,
  1962. + }, {
  1963. + .name = "mzk-w04nu:green:ap",
  1964. + .gpio = MZK_W04NU_GPIO_LED_AP,
  1965. + .active_low = 1,
  1966. + }, {
  1967. + .name = "mzk-w04nu:green:router",
  1968. + .gpio = MZK_W04NU_GPIO_LED_ROUTER,
  1969. + .active_low = 1,
  1970. + }
  1971. +};
  1972. +
  1973. +static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = {
  1974. + {
  1975. + .desc = "reset",
  1976. + .type = EV_KEY,
  1977. + .code = BTN_0,
  1978. + .threshold = 5,
  1979. + .gpio = MZK_W04NU_GPIO_BTN_RESET,
  1980. + .active_low = 1,
  1981. + }, {
  1982. + .desc = "wps",
  1983. + .type = EV_KEY,
  1984. + .code = BTN_1,
  1985. + .threshold = 5,
  1986. + .gpio = MZK_W04NU_GPIO_BTN_WPS,
  1987. + .active_low = 1,
  1988. + }, {
  1989. + .desc = "aprouter",
  1990. + .type = EV_KEY,
  1991. + .code = BTN_2,
  1992. + .threshold = 5,
  1993. + .gpio = MZK_W04NU_GPIO_BTN_APROUTER,
  1994. + .active_low = 0,
  1995. + }
  1996. +};
  1997. +
  1998. +static void __init mzk_w04nu_setup(void)
  1999. +{
  2000. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff1000);
  2001. +
  2002. + ar71xx_set_mac_base(mac);
  2003. +
  2004. + ar71xx_add_device_mdio(0x0);
  2005. +
  2006. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2007. + ar71xx_eth0_data.phy_mask = 0xf;
  2008. + ar71xx_eth0_data.speed = SPEED_100;
  2009. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2010. + ar71xx_eth0_data.has_ar8216 = 1;
  2011. +
  2012. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2013. + ar71xx_eth1_data.phy_mask = 0x10;
  2014. +
  2015. + ar71xx_add_device_eth(0);
  2016. + ar71xx_add_device_eth(1);
  2017. +
  2018. + ar71xx_add_device_spi(NULL, mzk_w04nu_spi_info,
  2019. + ARRAY_SIZE(mzk_w04nu_spi_info));
  2020. +
  2021. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
  2022. + mzk_w04nu_leds_gpio);
  2023. +
  2024. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  2025. + ARRAY_SIZE(mzk_w04nu_gpio_buttons),
  2026. + mzk_w04nu_gpio_buttons);
  2027. + ar71xx_add_device_usb();
  2028. +
  2029. + ar91xx_add_device_wmac();
  2030. +}
  2031. +
  2032. +MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "Planex MZK-W04NU", mzk_w04nu_setup);
  2033. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w300nh.c
  2034. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100
  2035. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w300nh.c 2009-04-13 14:27:34.551067888 +0200
  2036. @@ -0,0 +1,81 @@
  2037. +/*
  2038. + * Planex MZK-W300NH board support
  2039. + *
  2040. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2041. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2042. + *
  2043. + * This program is free software; you can redistribute it and/or modify it
  2044. + * under the terms of the GNU General Public License version 2 as published
  2045. + * by the Free Software Foundation.
  2046. + */
  2047. +
  2048. +#include <linux/platform_device.h>
  2049. +#include <linux/mtd/mtd.h>
  2050. +#include <linux/mtd/partitions.h>
  2051. +#include <linux/spi/spi.h>
  2052. +#include <linux/spi/flash.h>
  2053. +
  2054. +#include <asm/mips_machine.h>
  2055. +
  2056. +#include <asm/mach-ar71xx/ar71xx.h>
  2057. +
  2058. +#include "devices.h"
  2059. +
  2060. +#ifdef CONFIG_MTD_PARTITIONS
  2061. +static struct mtd_partition mzk_w300nh_partitions[] = {
  2062. + {
  2063. + .name = "u-boot",
  2064. + .offset = 0,
  2065. + .size = 0x040000,
  2066. + .mask_flags = MTD_WRITEABLE,
  2067. + } , {
  2068. + .name = "u-boot-env",
  2069. + .offset = 0x040000,
  2070. + .size = 0x010000,
  2071. + } , {
  2072. + .name = "uImage",
  2073. + .offset = 0x050000,
  2074. + .size = 0x160000,
  2075. + } , {
  2076. + .name = "rootfs",
  2077. + .offset = 0x1b0000,
  2078. + .size = 0x610000,
  2079. + } , {
  2080. + .name = "config",
  2081. + .offset = 0x7c0000,
  2082. + .size = 0x020000,
  2083. + } , {
  2084. + .name = "art",
  2085. + .offset = 0x7e0000,
  2086. + .size = 0x020000,
  2087. + .mask_flags = MTD_WRITEABLE,
  2088. + }
  2089. +};
  2090. +#endif /* CONFIG_MTD_PARTITIONS */
  2091. +
  2092. +static struct flash_platform_data mzk_w300nh_flash_data = {
  2093. +#ifdef CONFIG_MTD_PARTITIONS
  2094. + .parts = mzk_w300nh_partitions,
  2095. + .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions),
  2096. +#endif
  2097. +};
  2098. +
  2099. +static struct spi_board_info mzk_w300nh_spi_info[] = {
  2100. + {
  2101. + .bus_num = 0,
  2102. + .chip_select = 0,
  2103. + .max_speed_hz = 25000000,
  2104. + .modalias = "m25p80",
  2105. + .platform_data = &mzk_w300nh_flash_data,
  2106. + }
  2107. +};
  2108. +
  2109. +static void __init mzk_w300nh_setup(void)
  2110. +{
  2111. + ar71xx_add_device_spi(NULL, mzk_w300nh_spi_info,
  2112. + ARRAY_SIZE(mzk_w300nh_spi_info));
  2113. +
  2114. + ar91xx_add_device_wmac();
  2115. +}
  2116. +
  2117. +MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "Planex MZK-W300NH", mzk_w300nh_setup);
  2118. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.29.1/arch/mips/ar71xx/mach-pb42.c
  2119. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100
  2120. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-pb42.c 2009-04-13 14:27:34.555068677 +0200
  2121. @@ -0,0 +1,102 @@
  2122. +/*
  2123. + * Atheros PB42 board support
  2124. + *
  2125. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2126. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2127. + *
  2128. + * This program is free software; you can redistribute it and/or modify it
  2129. + * under the terms of the GNU General Public License version 2 as published
  2130. + * by the Free Software Foundation.
  2131. + */
  2132. +
  2133. +#include <linux/init.h>
  2134. +#include <linux/bitops.h>
  2135. +#include <linux/input.h>
  2136. +#include <linux/platform_device.h>
  2137. +#include <linux/spi/spi.h>
  2138. +#include <linux/spi/flash.h>
  2139. +
  2140. +#include <asm/mips_machine.h>
  2141. +#include <asm/mach-ar71xx/ar71xx.h>
  2142. +#include <asm/mach-ar71xx/pci.h>
  2143. +
  2144. +#include "devices.h"
  2145. +
  2146. +#define PB42_BUTTONS_POLL_INTERVAL 20
  2147. +
  2148. +#define PB42_GPIO_BTN_SW4 8
  2149. +#define PB42_GPIO_BTN_SW5 3
  2150. +
  2151. +static struct spi_board_info pb42_spi_info[] = {
  2152. + {
  2153. + .bus_num = 0,
  2154. + .chip_select = 0,
  2155. + .max_speed_hz = 25000000,
  2156. + .modalias = "m25p80",
  2157. + }
  2158. +};
  2159. +
  2160. +static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
  2161. + {
  2162. + .slot = 0,
  2163. + .pin = 1,
  2164. + .irq = AR71XX_PCI_IRQ_DEV0,
  2165. + }, {
  2166. + .slot = 1,
  2167. + .pin = 1,
  2168. + .irq = AR71XX_PCI_IRQ_DEV1,
  2169. + }, {
  2170. + .slot = 2,
  2171. + .pin = 1,
  2172. + .irq = AR71XX_PCI_IRQ_DEV2,
  2173. + }
  2174. +};
  2175. +
  2176. +static struct gpio_button pb42_gpio_buttons[] __initdata = {
  2177. + {
  2178. + .desc = "sw4",
  2179. + .type = EV_KEY,
  2180. + .code = BTN_0,
  2181. + .threshold = 5,
  2182. + .gpio = PB42_GPIO_BTN_SW4,
  2183. + .active_low = 1,
  2184. + } , {
  2185. + .desc = "sw5",
  2186. + .type = EV_KEY,
  2187. + .code = BTN_1,
  2188. + .threshold = 5,
  2189. + .gpio = PB42_GPIO_BTN_SW5,
  2190. + .active_low = 1,
  2191. + }
  2192. +};
  2193. +
  2194. +#define PB42_WAN_PHYMASK BIT(20)
  2195. +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  2196. +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
  2197. +
  2198. +static void __init pb42_init(void)
  2199. +{
  2200. + ar71xx_add_device_spi(NULL, pb42_spi_info,
  2201. + ARRAY_SIZE(pb42_spi_info));
  2202. +
  2203. + ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
  2204. +
  2205. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2206. + ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
  2207. +
  2208. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2209. + ar71xx_eth1_data.phy_mask = PB42_LAN_PHYMASK;
  2210. + ar71xx_eth1_data.speed = SPEED_100;
  2211. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  2212. +
  2213. + ar71xx_add_device_eth(0);
  2214. + ar71xx_add_device_eth(1);
  2215. +
  2216. + ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL,
  2217. + ARRAY_SIZE(pb42_gpio_buttons),
  2218. + pb42_gpio_buttons);
  2219. +
  2220. + ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
  2221. +}
  2222. +
  2223. +MIPS_MACHINE(AR71XX_MACH_PB42, "Atheros PB42", pb42_init);
  2224. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-rb-4xx.c linux-2.6.29.1/arch/mips/ar71xx/mach-rb-4xx.c
  2225. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-rb-4xx.c 1970-01-01 01:00:00.000000000 +0100
  2226. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-rb-4xx.c 2009-04-13 14:27:34.555068677 +0200
  2227. @@ -0,0 +1,251 @@
  2228. +/*
  2229. + * MikroTik RouterBOARD 4xx series support
  2230. + *
  2231. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  2232. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2233. + *
  2234. + * This program is free software; you can redistribute it and/or modify it
  2235. + * under the terms of the GNU General Public License version 2 as published
  2236. + * by the Free Software Foundation.
  2237. + */
  2238. +
  2239. +#include <linux/platform_device.h>
  2240. +#include <linux/irq.h>
  2241. +#include <linux/mmc/host.h>
  2242. +#include <linux/spi/spi.h>
  2243. +#include <linux/spi/flash.h>
  2244. +#include <linux/spi/mmc_spi.h>
  2245. +#include <linux/input.h>
  2246. +
  2247. +#include <asm/mips_machine.h>
  2248. +#include <asm/mach-ar71xx/ar71xx.h>
  2249. +#include <asm/mach-ar71xx/pci.h>
  2250. +
  2251. +#include "devices.h"
  2252. +
  2253. +#define RB4XX_GPIO_USER_LED 4
  2254. +#define RB4XX_GPIO_RESET_SWITCH 7
  2255. +
  2256. +#define RB4XX_BUTTONS_POLL_INTERVAL 20
  2257. +
  2258. +static struct gpio_led rb4xx_leds_gpio[] __initdata = {
  2259. + {
  2260. + .name = "rb4xx:yellow:user",
  2261. + .gpio = RB4XX_GPIO_USER_LED,
  2262. + .active_low = 0,
  2263. + },
  2264. +};
  2265. +
  2266. +static struct gpio_button rb4xx_gpio_buttons[] __initdata = {
  2267. + {
  2268. + .desc = "reset_switch",
  2269. + .type = EV_KEY,
  2270. + .code = BTN_0,
  2271. + .threshold = 5,
  2272. + .gpio = RB4XX_GPIO_RESET_SWITCH,
  2273. + .active_low = 1,
  2274. + }
  2275. +};
  2276. +
  2277. +static struct platform_device rb4xx_nand_device = {
  2278. + .name = "rb4xx-nand",
  2279. + .id = -1,
  2280. +};
  2281. +
  2282. +static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
  2283. + {
  2284. + .slot = 1,
  2285. + .pin = 1,
  2286. + .irq = AR71XX_PCI_IRQ_DEV0,
  2287. + }, {
  2288. + .slot = 1,
  2289. + .pin = 2,
  2290. + .irq = AR71XX_PCI_IRQ_DEV1,
  2291. + }, {
  2292. + .slot = 2,
  2293. + .pin = 1,
  2294. + .irq = AR71XX_PCI_IRQ_DEV1,
  2295. + }, {
  2296. + .slot = 3,
  2297. + .pin = 1,
  2298. + .irq = AR71XX_PCI_IRQ_DEV2,
  2299. + }
  2300. +};
  2301. +
  2302. +#if 0
  2303. +/*
  2304. + * SPI device support is experimental
  2305. + */
  2306. +static struct flash_platform_data rb4xx_flash_data = {
  2307. + .type = "pm25lv512",
  2308. +};
  2309. +
  2310. +static struct spi_board_info rb4xx_spi_info[] = {
  2311. + {
  2312. + .bus_num = 0,
  2313. + .chip_select = 0,
  2314. + .max_speed_hz = 25000000,
  2315. + .modalias = "m25p80",
  2316. + .platform_data = &rb4xx_flash_data,
  2317. + }
  2318. +};
  2319. +
  2320. +static struct mmc_spi_platform_data rb433_mmc_data = {
  2321. + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
  2322. +};
  2323. +
  2324. +static struct spi_board_info rb433_spi_info[] = {
  2325. + {
  2326. + .bus_num = 0,
  2327. + .chip_select = 0,
  2328. + .max_speed_hz = 25000000,
  2329. + .modalias = "m25p80",
  2330. + .platform_data = &rb433_flash_data,
  2331. + }, {
  2332. + .bus_num = 0,
  2333. + .chip_select = 2,
  2334. + .max_speed_hz = 25000000,
  2335. + .modalias = "mmc_spi",
  2336. + .platform_data = &rb433_mmc_data,
  2337. + }
  2338. +};
  2339. +
  2340. +static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  2341. +{
  2342. + u32 ret;
  2343. +
  2344. + if (is_on == AR71XX_SPI_CS_INACTIVE) {
  2345. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  2346. + } else {
  2347. + if (cs_high) {
  2348. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  2349. + } else {
  2350. + if ((chip_select ^ 2) == 0)
  2351. + ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  2352. + else
  2353. + ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  2354. + }
  2355. + }
  2356. +
  2357. + return ret;
  2358. +}
  2359. +
  2360. +struct ar71xx_spi_platform_data rb433_spi_data = {
  2361. + .bus_num = 0,
  2362. + .num_chipselect = 3,
  2363. + .get_ioc_base = rb433_spi_get_ioc_base,
  2364. +};
  2365. +
  2366. +static void rb4xx_add_device_spi(void)
  2367. +{
  2368. + ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
  2369. +}
  2370. +
  2371. +static void rb433_add_device_spi(void)
  2372. +{
  2373. + ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info,
  2374. + ARRAY_SIZE(rb433_spi_info));
  2375. +}
  2376. +#else
  2377. +static inline void rb4xx_add_device_spi(void) {}
  2378. +static inline void rb433_add_device_spi(void) {}
  2379. +#endif
  2380. +
  2381. +static void __init rb4xx_generic_setup(void)
  2382. +{
  2383. + ar71xx_gpio_function_enable(GPIO_FUNC_SPI_CS1_EN |
  2384. + GPIO_FUNC_SPI_CS2_EN);
  2385. +
  2386. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
  2387. + rb4xx_leds_gpio);
  2388. +
  2389. + ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL,
  2390. + ARRAY_SIZE(rb4xx_gpio_buttons),
  2391. + rb4xx_gpio_buttons);
  2392. +
  2393. + platform_device_register(&rb4xx_nand_device);
  2394. +}
  2395. +
  2396. +static void __init rb411_setup(void)
  2397. +{
  2398. + rb4xx_generic_setup();
  2399. + rb4xx_add_device_spi();
  2400. +
  2401. + ar71xx_add_device_mdio(0xfffffffe);
  2402. +
  2403. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2404. + ar71xx_eth0_data.phy_mask = 0x00000001;
  2405. +
  2406. + ar71xx_add_device_eth(0);
  2407. +
  2408. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  2409. +}
  2410. +
  2411. +MIPS_MACHINE(AR71XX_MACH_RB_411, "MikroTik RouterBOARD 411/A/AH", rb411_setup);
  2412. +
  2413. +static void __init rb433_setup(void)
  2414. +{
  2415. + rb4xx_generic_setup();
  2416. + rb433_add_device_spi();
  2417. +
  2418. + ar71xx_add_device_mdio(0xffffffe9);
  2419. +
  2420. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2421. + ar71xx_eth0_data.phy_mask = 0x00000006;
  2422. + ar71xx_eth0_data.speed = SPEED_100;
  2423. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2424. +
  2425. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2426. + ar71xx_eth1_data.phy_mask = 0x00000010;
  2427. +
  2428. + ar71xx_add_device_eth(1);
  2429. + ar71xx_add_device_eth(0);
  2430. +
  2431. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  2432. +}
  2433. +
  2434. +MIPS_MACHINE(AR71XX_MACH_RB_433, "MikroTik RouterBOARD 433/AH", rb433_setup);
  2435. +
  2436. +static void __init rb450_setup(void)
  2437. +{
  2438. + rb4xx_generic_setup();
  2439. + rb4xx_add_device_spi();
  2440. +
  2441. + ar71xx_add_device_mdio(0xffffffe0);
  2442. +
  2443. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2444. + ar71xx_eth0_data.phy_mask = 0x0000000f;
  2445. + ar71xx_eth0_data.speed = SPEED_100;
  2446. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2447. +
  2448. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2449. + ar71xx_eth1_data.phy_mask = 0x00000010;
  2450. +
  2451. + ar71xx_add_device_eth(1);
  2452. + ar71xx_add_device_eth(0);
  2453. +}
  2454. +
  2455. +MIPS_MACHINE(AR71XX_MACH_RB_450, "MikroTik RouterBOARD 450", rb450_setup);
  2456. +
  2457. +static void __init rb493_setup(void)
  2458. +{
  2459. + rb4xx_generic_setup();
  2460. + rb4xx_add_device_spi();
  2461. +
  2462. + ar71xx_add_device_mdio(0x3fffff00);
  2463. +
  2464. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2465. + ar71xx_eth0_data.phy_mask = 0;
  2466. + ar71xx_eth0_data.speed = SPEED_100;
  2467. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2468. +
  2469. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2470. + ar71xx_eth1_data.phy_mask = 0x00000001;
  2471. +
  2472. + ar71xx_add_device_eth(0);
  2473. + ar71xx_add_device_eth(1);
  2474. +
  2475. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  2476. +}
  2477. +
  2478. +MIPS_MACHINE(AR71XX_MACH_RB_493, "MikroTik RouterBOARD 493/AH", rb493_setup);
  2479. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.29.1/arch/mips/ar71xx/mach-tew-632brp.c
  2480. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100
  2481. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-tew-632brp.c 2009-04-13 14:27:34.559070024 +0200
  2482. @@ -0,0 +1,142 @@
  2483. +/*
  2484. + * TrendNET TEW-632BRP board support
  2485. + *
  2486. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2487. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2488. + *
  2489. + * This program is free software; you can redistribute it and/or modify it
  2490. + * under the terms of the GNU General Public License version 2 as published
  2491. + * by the Free Software Foundation.
  2492. + */
  2493. +
  2494. +#include <linux/platform_device.h>
  2495. +#include <linux/mtd/mtd.h>
  2496. +#include <linux/mtd/partitions.h>
  2497. +#include <linux/spi/spi.h>
  2498. +#include <linux/spi/flash.h>
  2499. +#include <linux/input.h>
  2500. +
  2501. +#include <asm/mips_machine.h>
  2502. +
  2503. +#include <asm/mach-ar71xx/ar71xx.h>
  2504. +
  2505. +#include "devices.h"
  2506. +
  2507. +#define TEW_632BRP_GPIO_LED_STATUS 1
  2508. +#define TEW_632BRP_GPIO_LED_WPS 3
  2509. +#define TEW_632BRP_GPIO_LED_WLAN 6
  2510. +#define TEW_632BRP_GPIO_BTN_WPS 12
  2511. +#define TEW_632BRP_GPIO_BTN_RESET 21
  2512. +
  2513. +#define TEW_632BRP_BUTTONS_POLL_INTERVAL 20
  2514. +
  2515. +#ifdef CONFIG_MTD_PARTITIONS
  2516. +static struct mtd_partition tew_632brp_partitions[] = {
  2517. + {
  2518. + .name = "u-boot",
  2519. + .offset = 0,
  2520. + .size = 0x020000,
  2521. + .mask_flags = MTD_WRITEABLE,
  2522. + } , {
  2523. + .name = "config",
  2524. + .offset = 0x020000,
  2525. + .size = 0x010000,
  2526. + } , {
  2527. + .name = "kernel",
  2528. + .offset = 0x030000,
  2529. + .size = 0x0c0000,
  2530. + } , {
  2531. + .name = "rootfs",
  2532. + .offset = 0x0f0000,
  2533. + .size = 0x300000,
  2534. + } , {
  2535. + .name = "art",
  2536. + .offset = 0x3f0000,
  2537. + .size = 0x010000,
  2538. + .mask_flags = MTD_WRITEABLE,
  2539. + } , {
  2540. + .name = "firmware",
  2541. + .offset = 0x030000,
  2542. + .size = 0x3c0000,
  2543. + }
  2544. +};
  2545. +#endif /* CONFIG_MTD_PARTITIONS */
  2546. +
  2547. +static struct flash_platform_data tew_632brp_flash_data = {
  2548. +#ifdef CONFIG_MTD_PARTITIONS
  2549. + .parts = tew_632brp_partitions,
  2550. + .nr_parts = ARRAY_SIZE(tew_632brp_partitions),
  2551. +#endif
  2552. +};
  2553. +
  2554. +static struct spi_board_info tew_632brp_spi_info[] = {
  2555. + {
  2556. + .bus_num = 0,
  2557. + .chip_select = 0,
  2558. + .max_speed_hz = 25000000,
  2559. + .modalias = "m25p80",
  2560. + .platform_data = &tew_632brp_flash_data,
  2561. + }
  2562. +};
  2563. +
  2564. +static struct gpio_led tew_632brp_leds_gpio[] __initdata = {
  2565. + {
  2566. + .name = "tew-632brp:green:status",
  2567. + .gpio = TEW_632BRP_GPIO_LED_STATUS,
  2568. + .active_low = 1,
  2569. + }, {
  2570. + .name = "tew-632brp:blue:wps",
  2571. + .gpio = TEW_632BRP_GPIO_LED_WPS,
  2572. + .active_low = 1,
  2573. + }, {
  2574. + .name = "tew-632brp:green:wlan",
  2575. + .gpio = TEW_632BRP_GPIO_LED_WLAN,
  2576. + .active_low = 1,
  2577. + }
  2578. +};
  2579. +
  2580. +static struct gpio_button tew_632brp_gpio_buttons[] __initdata = {
  2581. + {
  2582. + .desc = "reset",
  2583. + .type = EV_KEY,
  2584. + .code = BTN_0,
  2585. + .threshold = 5,
  2586. + .gpio = TEW_632BRP_GPIO_BTN_RESET,
  2587. + }, {
  2588. + .desc = "wps",
  2589. + .type = EV_KEY,
  2590. + .code = BTN_1,
  2591. + .threshold = 5,
  2592. + .gpio = TEW_632BRP_GPIO_BTN_WPS,
  2593. + }
  2594. +};
  2595. +
  2596. +static void __init tew_632brp_setup(void)
  2597. +{
  2598. + ar71xx_add_device_mdio(0x0);
  2599. +
  2600. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2601. + ar71xx_eth0_data.phy_mask = 0xf;
  2602. + ar71xx_eth0_data.speed = SPEED_100;
  2603. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2604. +
  2605. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2606. + ar71xx_eth1_data.phy_mask = 0x10;
  2607. +
  2608. + ar71xx_add_device_eth(0);
  2609. + ar71xx_add_device_eth(1);
  2610. +
  2611. + ar71xx_add_device_spi(NULL, tew_632brp_spi_info,
  2612. + ARRAY_SIZE(tew_632brp_spi_info));
  2613. +
  2614. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio),
  2615. + tew_632brp_leds_gpio);
  2616. +
  2617. + ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL,
  2618. + ARRAY_SIZE(tew_632brp_gpio_buttons),
  2619. + tew_632brp_gpio_buttons);
  2620. +
  2621. + ar91xx_add_device_wmac();
  2622. +}
  2623. +
  2624. +MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TRENDnet TEW-632BRP", tew_632brp_setup);
  2625. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.29.1/arch/mips/ar71xx/mach-tl-wr941nd.c
  2626. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100
  2627. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-tl-wr941nd.c 2009-04-13 14:27:34.591071588 +0200
  2628. @@ -0,0 +1,144 @@
  2629. +/*
  2630. + * TP-LINK TL-WR941ND board support
  2631. + *
  2632. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  2633. + *
  2634. + * This program is free software; you can redistribute it and/or modify it
  2635. + * under the terms of the GNU General Public License version 2 as published
  2636. + * by the Free Software Foundation.
  2637. + */
  2638. +
  2639. +#include <linux/platform_device.h>
  2640. +#include <linux/mtd/mtd.h>
  2641. +#include <linux/mtd/partitions.h>
  2642. +#include <linux/spi/spi.h>
  2643. +#include <linux/spi/flash.h>
  2644. +#include <linux/input.h>
  2645. +
  2646. +#include <asm/mips_machine.h>
  2647. +
  2648. +#include <asm/mach-ar71xx/ar71xx.h>
  2649. +
  2650. +#include "devices.h"
  2651. +
  2652. +#define TL_WR941ND_GPIO_LED_SYSTEM 2
  2653. +#define TL_WR941ND_GPIO_LED_QSS 5
  2654. +
  2655. +#define TL_WR941ND_GPIO_BTN_RESET 3
  2656. +#define TL_WR941ND_GPIO_BTN_QSS 7
  2657. +
  2658. +#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20
  2659. +
  2660. +#ifdef CONFIG_MTD_PARTITIONS
  2661. +static struct mtd_partition tl_wr941nd_partitions[] = {
  2662. + {
  2663. + .name = "u-boot",
  2664. + .offset = 0,
  2665. + .size = 0x020000,
  2666. + .mask_flags = MTD_WRITEABLE,
  2667. + } , {
  2668. + .name = "kernel",
  2669. + .offset = 0x020000,
  2670. + .size = 0x120000,
  2671. + } , {
  2672. + .name = "rootfs",
  2673. + .offset = 0x140000,
  2674. + .size = 0x2b0000,
  2675. + } , {
  2676. + .name = "art",
  2677. + .offset = 0x3f0000,
  2678. + .size = 0x010000,
  2679. + .mask_flags = MTD_WRITEABLE,
  2680. + } , {
  2681. + .name = "firmware",
  2682. + .offset = 0x020000,
  2683. + .size = 0x3d0000,
  2684. + }
  2685. +};
  2686. +#endif /* CONFIG_MTD_PARTITIONS */
  2687. +
  2688. +static struct flash_platform_data tl_wr941nd_flash_data = {
  2689. +#ifdef CONFIG_MTD_PARTITIONS
  2690. + .parts = tl_wr941nd_partitions,
  2691. + .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions),
  2692. +#endif
  2693. +};
  2694. +
  2695. +static struct spi_board_info tl_wr941nd_spi_info[] = {
  2696. + {
  2697. + .bus_num = 0,
  2698. + .chip_select = 0,
  2699. + .max_speed_hz = 25000000,
  2700. + .modalias = "m25p80",
  2701. + .platform_data = &tl_wr941nd_flash_data,
  2702. + }
  2703. +};
  2704. +
  2705. +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = {
  2706. + {
  2707. + .name = "tl-wr941nd:green:system",
  2708. + .gpio = TL_WR941ND_GPIO_LED_SYSTEM,
  2709. + .active_low = 1,
  2710. + }, {
  2711. + .name = "tl-wr941nd:red:qss",
  2712. + .gpio = TL_WR941ND_GPIO_LED_QSS,
  2713. + .active_low = 1,
  2714. + }
  2715. +};
  2716. +
  2717. +static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = {
  2718. + {
  2719. + .desc = "reset",
  2720. + .type = EV_KEY,
  2721. + .code = BTN_0,
  2722. + .threshold = 5,
  2723. + .gpio = TL_WR941ND_GPIO_BTN_RESET,
  2724. + .active_low = 1,
  2725. + }, {
  2726. + .desc = "qss",
  2727. + .type = EV_KEY,
  2728. + .code = BTN_1,
  2729. + .threshold = 5,
  2730. + .gpio = TL_WR941ND_GPIO_BTN_QSS,
  2731. + .active_low = 1,
  2732. + }
  2733. +};
  2734. +
  2735. +static struct dsa_platform_data tl_wr941nd_dsa_data = {
  2736. + .port_names[0] = "wan",
  2737. + .port_names[1] = "lan1",
  2738. + .port_names[2] = "lan2",
  2739. + .port_names[3] = "lan3",
  2740. + .port_names[4] = "lan4",
  2741. + .port_names[5] = "cpu",
  2742. +};
  2743. +
  2744. +static void __init tl_wr941nd_setup(void)
  2745. +{
  2746. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  2747. +
  2748. + ar71xx_set_mac_base(mac);
  2749. +
  2750. + ar71xx_add_device_mdio(0x0);
  2751. +
  2752. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2753. + ar71xx_eth0_data.phy_mask = 0x0;
  2754. + ar71xx_eth0_data.speed = SPEED_100;
  2755. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  2756. +
  2757. + ar71xx_add_device_eth(0);
  2758. + ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data);
  2759. +
  2760. + ar71xx_add_device_spi(NULL, tl_wr941nd_spi_info,
  2761. + ARRAY_SIZE(tl_wr941nd_spi_info));
  2762. +
  2763. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio),
  2764. + tl_wr941nd_leds_gpio);
  2765. +
  2766. + ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL,
  2767. + ARRAY_SIZE(tl_wr941nd_gpio_buttons),
  2768. + tl_wr941nd_gpio_buttons);
  2769. + ar91xx_add_device_wmac();
  2770. +}
  2771. +
  2772. +MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TP-LINK TL-WR941ND", tl_wr941nd_setup);
  2773. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.29.1/arch/mips/ar71xx/mach-ubnt.c
  2774. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100
  2775. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-ubnt.c 2009-04-13 14:27:34.591071588 +0200
  2776. @@ -0,0 +1,188 @@
  2777. +/*
  2778. + * Ubiquiti RouterStation support
  2779. + *
  2780. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2781. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2782. + * Copyright (C) 2008 Ubiquiti <support@ubnt.com>
  2783. + *
  2784. + * This program is free software; you can redistribute it and/or modify it
  2785. + * under the terms of the GNU General Public License version 2 as published
  2786. + * by the Free Software Foundation.
  2787. + */
  2788. +
  2789. +#include <linux/platform_device.h>
  2790. +#include <linux/spi/spi.h>
  2791. +#include <linux/spi/flash.h>
  2792. +#include <linux/input.h>
  2793. +
  2794. +#include <asm/mips_machine.h>
  2795. +#include <asm/mach-ar71xx/ar71xx.h>
  2796. +#include <asm/mach-ar71xx/pci.h>
  2797. +
  2798. +#include "devices.h"
  2799. +
  2800. +#define UBNT_RS_GPIO_LED_RF 2
  2801. +#define UBNT_RS_GPIO_SW4 8
  2802. +
  2803. +#define UBNT_LS_SR71_GPIO_LED_D25 0
  2804. +#define UBNT_LS_SR71_GPIO_LED_D26 1
  2805. +#define UBNT_LS_SR71_GPIO_LED_D24 2
  2806. +#define UBNT_LS_SR71_GPIO_LED_D23 4
  2807. +#define UBNT_LS_SR71_GPIO_LED_D22 5
  2808. +#define UBNT_LS_SR71_GPIO_LED_D27 6
  2809. +#define UBNT_LS_SR71_GPIO_LED_D28 7
  2810. +
  2811. +#define UBNT_BUTTONS_POLL_INTERVAL 20
  2812. +
  2813. +static struct spi_board_info ubnt_spi_info[] = {
  2814. + {
  2815. + .bus_num = 0,
  2816. + .chip_select = 0,
  2817. + .max_speed_hz = 25000000,
  2818. + .modalias = "m25p80",
  2819. + }
  2820. +};
  2821. +
  2822. +static struct ar71xx_pci_irq ubnt_pci_irqs[] __initdata = {
  2823. + {
  2824. + .slot = 0,
  2825. + .pin = 1,
  2826. + .irq = AR71XX_PCI_IRQ_DEV0,
  2827. + }, {
  2828. + .slot = 1,
  2829. + .pin = 1,
  2830. + .irq = AR71XX_PCI_IRQ_DEV1,
  2831. + }, {
  2832. + .slot = 2,
  2833. + .pin = 1,
  2834. + .irq = AR71XX_PCI_IRQ_DEV2,
  2835. + }
  2836. +};
  2837. +
  2838. +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = {
  2839. + {
  2840. + .name = "ubnt:green:rf",
  2841. + .gpio = UBNT_RS_GPIO_LED_RF,
  2842. + .active_low = 0,
  2843. + }
  2844. +};
  2845. +
  2846. +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = {
  2847. + {
  2848. + .name = "ubnt:green:d22",
  2849. + .gpio = UBNT_LS_SR71_GPIO_LED_D22,
  2850. + .active_low = 0,
  2851. + }, {
  2852. + .name = "ubnt:green:d23",
  2853. + .gpio = UBNT_LS_SR71_GPIO_LED_D23,
  2854. + .active_low = 0,
  2855. + }, {
  2856. + .name = "ubnt:green:d24",
  2857. + .gpio = UBNT_LS_SR71_GPIO_LED_D24,
  2858. + .active_low = 0,
  2859. + }, {
  2860. + .name = "ubnt:red:d25",
  2861. + .gpio = UBNT_LS_SR71_GPIO_LED_D25,
  2862. + .active_low = 0,
  2863. + }, {
  2864. + .name = "ubnt:red:d26",
  2865. + .gpio = UBNT_LS_SR71_GPIO_LED_D26,
  2866. + .active_low = 0,
  2867. + }, {
  2868. + .name = "ubnt:green:d27",
  2869. + .gpio = UBNT_LS_SR71_GPIO_LED_D27,
  2870. + .active_low = 0,
  2871. + }, {
  2872. + .name = "ubnt:green:d28",
  2873. + .gpio = UBNT_LS_SR71_GPIO_LED_D28,
  2874. + .active_low = 0,
  2875. + }
  2876. +};
  2877. +
  2878. +static struct gpio_button ubnt_gpio_buttons[] __initdata = {
  2879. + {
  2880. + .desc = "sw4",
  2881. + .type = EV_KEY,
  2882. + .code = BTN_0,
  2883. + .threshold = 5,
  2884. + .gpio = UBNT_RS_GPIO_SW4,
  2885. + .active_low = 1,
  2886. + }
  2887. +};
  2888. +
  2889. +static void __init ubnt_generic_setup(void)
  2890. +{
  2891. + ar71xx_add_device_spi(NULL, ubnt_spi_info,
  2892. + ARRAY_SIZE(ubnt_spi_info));
  2893. +
  2894. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  2895. + ARRAY_SIZE(ubnt_gpio_buttons),
  2896. + ubnt_gpio_buttons);
  2897. +
  2898. + ar71xx_pci_init(ARRAY_SIZE(ubnt_pci_irqs), ubnt_pci_irqs);
  2899. +}
  2900. +
  2901. +#define UBNT_RS_WAN_PHYMASK (1 << 20)
  2902. +#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19))
  2903. +
  2904. +static void __init ubnt_rs_setup(void)
  2905. +{
  2906. + ubnt_generic_setup();
  2907. +
  2908. + ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK));
  2909. +
  2910. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2911. + ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK;
  2912. +
  2913. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  2914. + ar71xx_eth1_data.phy_mask = UBNT_RS_LAN_PHYMASK;
  2915. +
  2916. + ar71xx_eth1_data.speed = SPEED_100;
  2917. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  2918. +
  2919. + ar71xx_add_device_eth(0);
  2920. + ar71xx_add_device_eth(1);
  2921. +
  2922. + ar71xx_add_device_usb();
  2923. +
  2924. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  2925. + ubnt_rs_leds_gpio);
  2926. +}
  2927. +
  2928. +MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "Ubiquiti RouterStation", ubnt_rs_setup);
  2929. +
  2930. +static void __init ubnt_rspro_setup(void)
  2931. +{
  2932. + ubnt_generic_setup();
  2933. +
  2934. + ar71xx_add_device_usb();
  2935. +}
  2936. +
  2937. +MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "Ubiquiti RouterStation Pro",
  2938. + ubnt_rspro_setup);
  2939. +
  2940. +static void __init ubnt_lsx_setup(void)
  2941. +{
  2942. + ubnt_generic_setup();
  2943. +}
  2944. +
  2945. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "Ubiquiti LSX", ubnt_lsx_setup);
  2946. +
  2947. +#define UBNT_LSSR71_PHY_MASK (1 << 1)
  2948. +
  2949. +static void __init ubnt_lssr71_setup(void)
  2950. +{
  2951. + ubnt_generic_setup();
  2952. +
  2953. + ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK);
  2954. +
  2955. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  2956. + ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK;
  2957. +
  2958. + ar71xx_add_device_eth(0);
  2959. +
  2960. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio),
  2961. + ubnt_ls_sr71_leds_gpio);
  2962. +}
  2963. +
  2964. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "Ubiquiti LS-SR71", ubnt_lssr71_setup);
  2965. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.29.1/arch/mips/ar71xx/mach-wnr2000.c
  2966. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100
  2967. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-wnr2000.c 2009-04-13 14:27:34.595070701 +0200
  2968. @@ -0,0 +1,158 @@
  2969. +/*
  2970. + * NETGEAR WNR2000 board support
  2971. + *
  2972. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2973. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2974. + * Copyright (C) 2008-2009 Andy Boyett <agb@openwrt.org>
  2975. + *
  2976. + * This program is free software; you can redistribute it and/or modify it
  2977. + * under the terms of the GNU General Public License version 2 as published
  2978. + * by the Free Software Foundation.
  2979. + */
  2980. +
  2981. +#include <linux/platform_device.h>
  2982. +#include <linux/mtd/mtd.h>
  2983. +#include <linux/mtd/partitions.h>
  2984. +#include <linux/spi/spi.h>
  2985. +#include <linux/spi/flash.h>
  2986. +#include <linux/input.h>
  2987. +
  2988. +#include <asm/mips_machine.h>
  2989. +
  2990. +#include <asm/mach-ar71xx/ar71xx.h>
  2991. +
  2992. +#include "devices.h"
  2993. +
  2994. +#define WNR2000_GPIO_LED_PWR_GREEN 14
  2995. +#define WNR2000_GPIO_LED_PWR_AMBER 7
  2996. +#define WNR2000_GPIO_LED_WPS 4
  2997. +#define WNR2000_GPIO_LED_WLAN 6
  2998. +#define WNR2000_GPIO_BTN_RESET 21
  2999. +#define WNR2000_GPIO_BTN_WPS 8
  3000. +
  3001. +#define WNR2000_BUTTONS_POLL_INTERVAL 20
  3002. +
  3003. +#ifdef CONFIG_MTD_PARTITIONS
  3004. +static struct mtd_partition wnr2000_partitions[] = {
  3005. + {
  3006. + .name = "u-boot",
  3007. + .offset = 0,
  3008. + .size = 0x040000,
  3009. + .mask_flags = MTD_WRITEABLE,
  3010. + } , {
  3011. + .name = "u-boot-env",
  3012. + .offset = 0x040000,
  3013. + .size = 0x010000,
  3014. + } , {
  3015. + .name = "rootfs",
  3016. + .offset = 0x050000,
  3017. + .size = 0x240000,
  3018. + } , {
  3019. + .name = "user-config",
  3020. + .offset = 0x290000,
  3021. + .size = 0x010000,
  3022. + } , {
  3023. + .name = "uImage",
  3024. + .offset = 0x2a0000,
  3025. + .size = 0x120000,
  3026. + } , {
  3027. + .name = "language_table",
  3028. + .offset = 0x3c0000,
  3029. + .size = 0x020000,
  3030. + } , {
  3031. + .name = "rootfs_checksum",
  3032. + .offset = 0x3e0000,
  3033. + .size = 0x010000,
  3034. + } , {
  3035. + .name = "art",
  3036. + .offset = 0x3f0000,
  3037. + .size = 0x010000,
  3038. + .mask_flags = MTD_WRITEABLE,
  3039. + }
  3040. +};
  3041. +#endif /* CONFIG_MTD_PARTITIONS */
  3042. +
  3043. +static struct flash_platform_data wnr2000_flash_data = {
  3044. +#ifdef CONFIG_MTD_PARTITIONS
  3045. + .parts = wnr2000_partitions,
  3046. + .nr_parts = ARRAY_SIZE(wnr2000_partitions),
  3047. +#endif
  3048. +};
  3049. +
  3050. +static struct spi_board_info wnr2000_spi_info[] = {
  3051. + {
  3052. + .bus_num = 0,
  3053. + .chip_select = 0,
  3054. + .max_speed_hz = 25000000,
  3055. + .modalias = "m25p80",
  3056. + .platform_data = &wnr2000_flash_data,
  3057. + }
  3058. +};
  3059. +
  3060. +static struct gpio_led wnr2000_leds_gpio[] __initdata = {
  3061. + {
  3062. + .name = "wnr2000:green:power",
  3063. + .gpio = WNR2000_GPIO_LED_PWR_GREEN,
  3064. + .active_low = 1,
  3065. + }, {
  3066. + .name = "wnr2000:amber:power",
  3067. + .gpio = WNR2000_GPIO_LED_PWR_AMBER,
  3068. + .active_low = 1,
  3069. + }, {
  3070. + .name = "wnr2000:green:wps",
  3071. + .gpio = WNR2000_GPIO_LED_WPS,
  3072. + .active_low = 1,
  3073. + }, {
  3074. + .name = "wnr2000:blue:wlan",
  3075. + .gpio = WNR2000_GPIO_LED_WLAN,
  3076. + .active_low = 1,
  3077. + }
  3078. +};
  3079. +
  3080. +static struct gpio_button wnr2000_gpio_buttons[] __initdata = {
  3081. + {
  3082. + .desc = "reset",
  3083. + .type = EV_KEY,
  3084. + .code = BTN_0,
  3085. + .threshold = 5,
  3086. + .gpio = WNR2000_GPIO_BTN_RESET,
  3087. + }, {
  3088. + .desc = "wps",
  3089. + .type = EV_KEY,
  3090. + .code = BTN_1,
  3091. + .threshold = 5,
  3092. + .gpio = WNR2000_GPIO_BTN_WPS,
  3093. + }
  3094. +};
  3095. +
  3096. +static void __init wnr2000_setup(void)
  3097. +{
  3098. + ar71xx_add_device_mdio(0x0);
  3099. +
  3100. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3101. + ar71xx_eth0_data.phy_mask = 0xf;
  3102. + ar71xx_eth0_data.speed = SPEED_100;
  3103. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3104. + ar71xx_eth0_data.has_ar8216 = 1;
  3105. +
  3106. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3107. + ar71xx_eth1_data.phy_mask = 0x10;
  3108. +
  3109. + ar71xx_add_device_eth(0);
  3110. + ar71xx_add_device_eth(1);
  3111. +
  3112. + ar71xx_add_device_spi(NULL, wnr2000_spi_info,
  3113. + ARRAY_SIZE(wnr2000_spi_info));
  3114. +
  3115. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio),
  3116. + wnr2000_leds_gpio);
  3117. +
  3118. + ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL,
  3119. + ARRAY_SIZE(wnr2000_gpio_buttons),
  3120. + wnr2000_gpio_buttons);
  3121. +
  3122. +
  3123. + ar91xx_add_device_wmac();
  3124. +}
  3125. +
  3126. +MIPS_MACHINE(AR71XX_MACH_WNR2000, "NETGEAR WNR2000", wnr2000_setup);
  3127. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.29.1/arch/mips/ar71xx/mach-wp543.c
  3128. --- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100
  3129. +++ linux-2.6.29.1/arch/mips/ar71xx/mach-wp543.c 2009-04-13 14:27:34.595070701 +0200
  3130. @@ -0,0 +1,118 @@
  3131. +/*
  3132. + * Compex WP543 board support
  3133. + *
  3134. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3135. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3136. + *
  3137. + * This program is free software; you can redistribute it and/or modify it
  3138. + * under the terms of the GNU General Public License version 2 as published
  3139. + * by the Free Software Foundation.
  3140. + */
  3141. +
  3142. +#include <linux/platform_device.h>
  3143. +#include <linux/mtd/mtd.h>
  3144. +#include <linux/mtd/partitions.h>
  3145. +#include <linux/spi/spi.h>
  3146. +#include <linux/spi/flash.h>
  3147. +#include <linux/input.h>
  3148. +
  3149. +#include <asm/mips_machine.h>
  3150. +#include <asm/mach-ar71xx/ar71xx.h>
  3151. +#include <asm/mach-ar71xx/pci.h>
  3152. +
  3153. +#include "devices.h"
  3154. +
  3155. +#define WP543_GPIO_SW6 2
  3156. +#define WP543_GPIO_LED_1 3
  3157. +#define WP543_GPIO_LED_2 4
  3158. +#define WP543_GPIO_LED_WLAN 5
  3159. +#define WP543_GPIO_LED_CONN 6
  3160. +#define WP543_GPIO_LED_DIAG 7
  3161. +#define WP543_GPIO_SW4 8
  3162. +
  3163. +#define WP543_BUTTONS_POLL_INTERVAL 20
  3164. +
  3165. +static struct spi_board_info wp543_spi_info[] = {
  3166. + {
  3167. + .bus_num = 0,
  3168. + .chip_select = 0,
  3169. + .max_speed_hz = 25000000,
  3170. + .modalias = "m25p80",
  3171. + }
  3172. +};
  3173. +
  3174. +static struct ar71xx_pci_irq wp543_pci_irqs[] __initdata = {
  3175. + {
  3176. + .slot = 1,
  3177. + .pin = 1,
  3178. + .irq = AR71XX_PCI_IRQ_DEV0,
  3179. + }, {
  3180. + .slot = 1,
  3181. + .pin = 2,
  3182. + .irq = AR71XX_PCI_IRQ_DEV1,
  3183. + }
  3184. +};
  3185. +
  3186. +static struct gpio_led wp543_leds_gpio[] __initdata = {
  3187. + {
  3188. + .name = "wp543:green:led1",
  3189. + .gpio = WP543_GPIO_LED_1,
  3190. + .active_low = 1,
  3191. + }, {
  3192. + .name = "wp543:green:led2",
  3193. + .gpio = WP543_GPIO_LED_2,
  3194. + .active_low = 1,
  3195. + }, {
  3196. + .name = "wp543:green:wlan",
  3197. + .gpio = WP543_GPIO_LED_WLAN,
  3198. + .active_low = 1,
  3199. + }, {
  3200. + .name = "wp543:green:conn",
  3201. + .gpio = WP543_GPIO_LED_CONN,
  3202. + .active_low = 1,
  3203. + }, {
  3204. + .name = "wp543:green:diag",
  3205. + .gpio = WP543_GPIO_LED_DIAG,
  3206. + .active_low = 1,
  3207. + }
  3208. +};
  3209. +
  3210. +static struct gpio_button wp543_gpio_buttons[] __initdata = {
  3211. + {
  3212. + .desc = "sw6",
  3213. + .type = EV_KEY,
  3214. + .code = BTN_0,
  3215. + .threshold = 5,
  3216. + .gpio = WP543_GPIO_SW6,
  3217. + }, {
  3218. + .desc = "sw4",
  3219. + .type = EV_KEY,
  3220. + .code = BTN_1,
  3221. + .threshold = 5,
  3222. + .gpio = WP543_GPIO_SW4,
  3223. + }
  3224. +};
  3225. +
  3226. +static void __init wp543_setup(void)
  3227. +{
  3228. + ar71xx_add_device_spi(NULL, wp543_spi_info, ARRAY_SIZE(wp543_spi_info));
  3229. +
  3230. + ar71xx_add_device_mdio(0xfffffff7);
  3231. +
  3232. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  3233. + ar71xx_eth0_data.phy_mask = 0x00000008;
  3234. + ar71xx_add_device_eth(0);
  3235. +
  3236. + ar71xx_add_device_usb();
  3237. +
  3238. + ar71xx_pci_init(ARRAY_SIZE(wp543_pci_irqs), wp543_pci_irqs);
  3239. +
  3240. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio),
  3241. + wp543_leds_gpio);
  3242. +
  3243. + ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL,
  3244. + ARRAY_SIZE(wp543_gpio_buttons),
  3245. + wp543_gpio_buttons);
  3246. +}
  3247. +
  3248. +MIPS_MACHINE(AR71XX_MACH_WP543, "Compex WP543", wp543_setup);
  3249. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/prom.c linux-2.6.29.1/arch/mips/ar71xx/prom.c
  3250. --- linux-2.6.29.1.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100
  3251. +++ linux-2.6.29.1/arch/mips/ar71xx/prom.c 2009-04-13 14:27:34.595070701 +0200
  3252. @@ -0,0 +1,207 @@
  3253. +/*
  3254. + * Atheros AR71xx SoC specific prom routines
  3255. + *
  3256. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3257. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3258. + *
  3259. + * This program is free software; you can redistribute it and/or modify it
  3260. + * under the terms of the GNU General Public License version 2 as published
  3261. + * by the Free Software Foundation.
  3262. + */
  3263. +
  3264. +#include <linux/kernel.h>
  3265. +#include <linux/init.h>
  3266. +#include <linux/io.h>
  3267. +#include <linux/serial_reg.h>
  3268. +
  3269. +#include <asm/bootinfo.h>
  3270. +#include <asm/addrspace.h>
  3271. +
  3272. +#include <asm/mach-ar71xx/ar71xx.h>
  3273. +
  3274. +#include "devices.h"
  3275. +
  3276. +struct board_rec {
  3277. + char *name;
  3278. + unsigned long mach_type;
  3279. +};
  3280. +
  3281. +static int ar71xx_prom_argc __initdata;
  3282. +static char **ar71xx_prom_argv __initdata;
  3283. +static char **ar71xx_prom_envp __initdata;
  3284. +
  3285. +static struct board_rec boards[] __initdata = {
  3286. + {
  3287. + .name = "411",
  3288. + .mach_type = AR71XX_MACH_RB_411,
  3289. + }, {
  3290. + .name = "433",
  3291. + .mach_type = AR71XX_MACH_RB_433,
  3292. + }, {
  3293. + .name = "450",
  3294. + .mach_type = AR71XX_MACH_RB_450,
  3295. + }, {
  3296. + .name = "493",
  3297. + .mach_type = AR71XX_MACH_RB_493,
  3298. + }, {
  3299. + .name = "AP81",
  3300. + .mach_type = AR71XX_MACH_AP81,
  3301. + }, {
  3302. + .name = "AP83",
  3303. + .mach_type = AR71XX_MACH_AP83,
  3304. + }, {
  3305. + .name = "AW-NR580",
  3306. + .mach_type = AR71XX_MACH_AW_NR580,
  3307. + }, {
  3308. + .name = "TEW-632BRP",
  3309. + .mach_type = AR71XX_MACH_TEW_632BRP,
  3310. + }, {
  3311. + .name = "TL-WR941ND",
  3312. + .mach_type = AR71XX_MACH_TL_WR941ND,
  3313. + }, {
  3314. + .name = "UBNT-RS",
  3315. + .mach_type = AR71XX_MACH_UBNT_RS,
  3316. + }, {
  3317. + .name = "UBNT-RSPRO",
  3318. + .mach_type = AR71XX_MACH_UBNT_RSPRO,
  3319. + }, {
  3320. + .name = "Ubiquiti AR71xx-based board",
  3321. + .mach_type = AR71XX_MACH_UBNT_RS,
  3322. + }, {
  3323. + .name = "UBNT-LS-SR71",
  3324. + .mach_type = AR71XX_MACH_UBNT_LSSR71,
  3325. + }, {
  3326. + .name = "UBNT-LSX",
  3327. + .mach_type = AR71XX_MACH_UBNT_LSX,
  3328. + }, {
  3329. + .name = "WNR2000",
  3330. + .mach_type = AR71XX_MACH_WNR2000,
  3331. + }, {
  3332. + .name = "PB42",
  3333. + .mach_type = AR71XX_MACH_PB42,
  3334. + }, {
  3335. + .name = "MZK-W300NH",
  3336. + .mach_type = AR71XX_MACH_MZK_W300NH,
  3337. + }, {
  3338. + .name = "MZK-W04NU",
  3339. + .mach_type = AR71XX_MACH_MZK_W04NU,
  3340. + }
  3341. +};
  3342. +
  3343. +static inline int is_valid_ram_addr(void *addr)
  3344. +{
  3345. + if (((u32) addr > KSEG0) &&
  3346. + ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX)))
  3347. + return 1;
  3348. +
  3349. + if (((u32) addr > KSEG1) &&
  3350. + ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX)))
  3351. + return 1;
  3352. +
  3353. + return 0;
  3354. +}
  3355. +
  3356. +static __init char *ar71xx_prom_getargv(const char *name)
  3357. +{
  3358. + int len = strlen(name);
  3359. + int i;
  3360. +
  3361. + if (!is_valid_ram_addr(ar71xx_prom_argv))
  3362. + return NULL;
  3363. +
  3364. + for (i = 0; i < ar71xx_prom_argc; i++) {
  3365. + char *argv = ar71xx_prom_argv[i];
  3366. +
  3367. + if (!is_valid_ram_addr(argv))
  3368. + continue;
  3369. +
  3370. + if (strncmp(name, argv, len) == 0 && (argv)[len] == '=')
  3371. + return argv + len + 1;
  3372. + }
  3373. +
  3374. + return NULL;
  3375. +}
  3376. +
  3377. +static __init char *ar71xx_prom_getenv(const char *envname)
  3378. +{
  3379. + int len = strlen(envname);
  3380. + char **env;
  3381. +
  3382. + if (!is_valid_ram_addr(ar71xx_prom_envp))
  3383. + return NULL;
  3384. +
  3385. + for (env = ar71xx_prom_envp; is_valid_ram_addr(*env); env++) {
  3386. + if (strncmp(envname, *env, len) == 0 && (*env)[len] == '=')
  3387. + return *env + len + 1;
  3388. +
  3389. + /* RedBoot env comes in pointer pairs - key, value */
  3390. + if (strncmp(envname, *env, len) == 0 && (*env)[len] == 0)
  3391. + if (is_valid_ram_addr(*(++env)))
  3392. + return *env;
  3393. + }
  3394. +
  3395. + return NULL;
  3396. +}
  3397. +
  3398. +static __init unsigned long find_board_byname(char *name)
  3399. +{
  3400. + int i;
  3401. +
  3402. + for (i = 0; i < ARRAY_SIZE(boards); i++)
  3403. + if (strcmp(name, boards[i].name) == 0)
  3404. + return boards[i].mach_type;
  3405. +
  3406. + return AR71XX_MACH_GENERIC;
  3407. +}
  3408. +
  3409. +
  3410. +static void ar71xx_prom_init_generic(void)
  3411. +{
  3412. + char *p;
  3413. +
  3414. + ar71xx_prom_argc = fw_arg0;
  3415. + ar71xx_prom_argv = (char **)fw_arg1;
  3416. + ar71xx_prom_envp = (char **)fw_arg2;
  3417. +
  3418. + p = ar71xx_prom_getargv("board");
  3419. + if (!p)
  3420. + p = ar71xx_prom_getenv("board");
  3421. + if (p)
  3422. + ar71xx_mach_type = find_board_byname(p);
  3423. +
  3424. + p = ar71xx_prom_getenv("ethaddr");
  3425. + if (!p)
  3426. + p = ar71xx_prom_getargv("kmac");
  3427. + if (p)
  3428. + ar71xx_parse_mac_addr(p);
  3429. +}
  3430. +
  3431. +void __init prom_init(void)
  3432. +{
  3433. + printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, "
  3434. + "fw_arg2=%08x, fw_arg3=%08x\n",
  3435. + (unsigned int)fw_arg0, (unsigned int)fw_arg1,
  3436. + (unsigned int)fw_arg2, (unsigned int)fw_arg3);
  3437. +
  3438. + ar71xx_mach_type = AR71XX_MACH_GENERIC;
  3439. +
  3440. + ar71xx_prom_init_generic();
  3441. +}
  3442. +
  3443. +void __init prom_free_prom_memory(void)
  3444. +{
  3445. + /* We do not have to prom memory to free */
  3446. +}
  3447. +
  3448. +#define UART_READ(r) \
  3449. + __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r)))
  3450. +
  3451. +#define UART_WRITE(r, v) \
  3452. + __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r)))
  3453. +
  3454. +void prom_putchar(unsigned char ch)
  3455. +{
  3456. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  3457. + UART_WRITE(UART_TX, ch);
  3458. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  3459. +}
  3460. diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/setup.c linux-2.6.29.1/arch/mips/ar71xx/setup.c
  3461. --- linux-2.6.29.1.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100
  3462. +++ linux-2.6.29.1/arch/mips/ar71xx/setup.c 2009-04-13 14:27:34.599071210 +0200
  3463. @@ -0,0 +1,291 @@
  3464. +/*
  3465. + * Atheros AR71xx SoC specific setup
  3466. + *
  3467. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3468. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3469. + *
  3470. + * Parts of this file are based on Atheros' 2.6.15 BSP
  3471. + *
  3472. + * This program is free software; you can redistribute it and/or modify it
  3473. + * under the terms of the GNU General Public License version 2 as published
  3474. + * by the Free Software Foundation.
  3475. + */
  3476. +
  3477. +#include <linux/kernel.h>
  3478. +#include <linux/module.h>
  3479. +#include <linux/init.h>
  3480. +#include <linux/types.h>
  3481. +#include <linux/pci.h>
  3482. +#include <linux/serial_8250.h>
  3483. +#include <linux/bootmem.h>
  3484. +
  3485. +#include <asm/bootinfo.h>
  3486. +#include <asm/traps.h>
  3487. +#include <asm/time.h> /* for mips_hpt_frequency */
  3488. +#include <asm/reboot.h> /* for _machine_{restart,halt} */
  3489. +#include <asm/mips_machine.h>
  3490. +
  3491. +#include <asm/mach-ar71xx/ar71xx.h>
  3492. +#include <asm/mach-ar71xx/pci.h>
  3493. +
  3494. +#include "devices.h"
  3495. +
  3496. +#define AR71XX_SYS_TYPE_LEN 64
  3497. +#define AR71XX_BASE_FREQ 40000000
  3498. +#define AR91XX_BASE_FREQ 5000000
  3499. +
  3500. +unsigned long ar71xx_mach_type;
  3501. +
  3502. +u32 ar71xx_cpu_freq;
  3503. +EXPORT_SYMBOL_GPL(ar71xx_cpu_freq);
  3504. +
  3505. +u32 ar71xx_ahb_freq;
  3506. +EXPORT_SYMBOL_GPL(ar71xx_ahb_freq);
  3507. +
  3508. +u32 ar71xx_ddr_freq;
  3509. +EXPORT_SYMBOL_GPL(ar71xx_ddr_freq);
  3510. +
  3511. +enum ar71xx_soc_type ar71xx_soc;
  3512. +EXPORT_SYMBOL_GPL(ar71xx_soc);
  3513. +
  3514. +int (*ar71xx_pci_bios_init)(unsigned nr_irqs,
  3515. + struct ar71xx_pci_irq *map) __initdata;
  3516. +
  3517. +int (*ar71xx_pci_be_handler)(int is_fixup);
  3518. +
  3519. +static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];
  3520. +
  3521. +static void ar71xx_restart(char *command)
  3522. +{
  3523. + ar71xx_device_stop(RESET_MODULE_FULL_CHIP);
  3524. + for (;;)
  3525. + if (cpu_wait)
  3526. + cpu_wait();
  3527. +}
  3528. +
  3529. +static void ar71xx_halt(void)
  3530. +{
  3531. + while (1)
  3532. + cpu_wait();
  3533. +}
  3534. +
  3535. +static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
  3536. +{
  3537. + int err = 0;
  3538. +
  3539. + if (ar71xx_pci_be_handler)
  3540. + err = ar71xx_pci_be_handler(is_fixup);
  3541. +
  3542. + return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  3543. +}
  3544. +
  3545. +int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  3546. +{
  3547. + if (!ar71xx_pci_bios_init)
  3548. + return 0;
  3549. +
  3550. + return ar71xx_pci_bios_init(nr_irqs, map);
  3551. +}
  3552. +
  3553. +static void __init ar71xx_detect_mem_size(void)
  3554. +{
  3555. + unsigned long size;
  3556. +
  3557. + for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX;
  3558. + size <<= 1 ) {
  3559. + if (!memcmp(ar71xx_detect_mem_size,
  3560. + ar71xx_detect_mem_size + size, 1024))
  3561. + break;
  3562. + }
  3563. +
  3564. + add_memory_region(0, size, BOOT_MEM_RAM);
  3565. +}
  3566. +
  3567. +static void __init ar71xx_detect_sys_type(void)
  3568. +{
  3569. + char *chip;
  3570. + u32 id;
  3571. + u32 rev;
  3572. +
  3573. + id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID) & REV_ID_MASK;
  3574. + rev = (id >> REV_ID_REVISION_SHIFT) & REV_ID_REVISION_MASK;
  3575. +
  3576. + switch (id & REV_ID_CHIP_MASK) {
  3577. + case REV_ID_CHIP_AR7130:
  3578. + ar71xx_soc = AR71XX_SOC_AR7130;
  3579. + chip = "7130";
  3580. + break;
  3581. +
  3582. + case REV_ID_CHIP_AR7141:
  3583. + ar71xx_soc = AR71XX_SOC_AR7141;
  3584. + chip = "7141";
  3585. + break;
  3586. +
  3587. + case REV_ID_CHIP_AR7161:
  3588. + ar71xx_soc = AR71XX_SOC_AR7161;
  3589. + chip = "7161";
  3590. + break;
  3591. +
  3592. + case REV_ID_CHIP_AR9130:
  3593. + ar71xx_soc = AR71XX_SOC_AR9130;
  3594. + chip = "9130";
  3595. + break;
  3596. +
  3597. + case REV_ID_CHIP_AR9132:
  3598. + ar71xx_soc = AR71XX_SOC_AR9132;
  3599. + chip = "9132";
  3600. + break;
  3601. +
  3602. + default:
  3603. + panic("ar71xx: unknown chip id:0x%02x\n", id);
  3604. + }
  3605. +
  3606. + sprintf(ar71xx_sys_type, "Atheros AR%s rev %u (id:0x%02x)",
  3607. + chip, rev, id);
  3608. +}
  3609. +
  3610. +static void __init ar91xx_detect_sys_frequency(void)
  3611. +{
  3612. + u32 pll;
  3613. + u32 freq;
  3614. + u32 div;
  3615. +
  3616. + pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
  3617. +
  3618. + div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
  3619. + freq = div * AR91XX_BASE_FREQ;
  3620. +
  3621. + ar71xx_cpu_freq = freq;
  3622. +
  3623. + div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1;
  3624. + ar71xx_ddr_freq = freq / div;
  3625. +
  3626. + div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2;
  3627. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  3628. +}
  3629. +
  3630. +static void __init ar71xx_detect_sys_frequency(void)
  3631. +{
  3632. + u32 pll;
  3633. + u32 freq;
  3634. + u32 div;
  3635. +
  3636. + pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
  3637. +
  3638. + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
  3639. + freq = div * AR71XX_BASE_FREQ;
  3640. +
  3641. + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
  3642. + ar71xx_cpu_freq = freq / div;
  3643. +
  3644. + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
  3645. + ar71xx_ddr_freq = freq / div;
  3646. +
  3647. + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
  3648. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  3649. +}
  3650. +
  3651. +static void __init detect_sys_frequency(void)
  3652. +{
  3653. + switch (ar71xx_soc) {
  3654. + case AR71XX_SOC_AR7130:
  3655. + case AR71XX_SOC_AR7141:
  3656. + case AR71XX_SOC_AR7161:
  3657. + ar71xx_detect_sys_frequency();
  3658. + break;
  3659. +
  3660. + case AR71XX_SOC_AR9130:
  3661. + case AR71XX_SOC_AR9132:
  3662. + ar91xx_detect_sys_frequency();
  3663. + break;
  3664. +
  3665. + default:
  3666. + BUG();
  3667. + }
  3668. +}
  3669. +
  3670. +#ifdef CONFIG_AR71XX_EARLY_SERIAL
  3671. +static void __init ar71xx_early_serial_setup(void)
  3672. +{
  3673. + struct uart_port p;
  3674. +
  3675. + memset(&p, 0, sizeof(p));
  3676. +
  3677. + p.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP;
  3678. + p.iotype = UPIO_MEM32;
  3679. + p.uartclk = ar71xx_ahb_freq;
  3680. + p.irq = AR71XX_MISC_IRQ_UART;
  3681. + p.regshift = 2;
  3682. + p.mapbase = AR71XX_UART_BASE;
  3683. +
  3684. + early_serial_setup(&p);
  3685. +}
  3686. +#else
  3687. +static inline void ar71xx_early_serial_setup(void) {};
  3688. +#endif /* CONFIG_AR71XX_EARLY_SERIAL */
  3689. +
  3690. +const char *get_system_type(void)
  3691. +{
  3692. + return ar71xx_sys_type;
  3693. +}
  3694. +
  3695. +unsigned int __cpuinit get_c0_compare_irq(void)
  3696. +{
  3697. + return CP0_LEGACY_COMPARE_IRQ;
  3698. +}
  3699. +
  3700. +void __init plat_mem_setup(void)
  3701. +{
  3702. + set_io_port_base(KSEG1);
  3703. +
  3704. + ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
  3705. + AR71XX_DDR_CTRL_SIZE);
  3706. +
  3707. + ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
  3708. + AR71XX_PLL_SIZE);
  3709. +
  3710. + ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
  3711. + AR71XX_RESET_SIZE);
  3712. +
  3713. + ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  3714. +
  3715. + ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE,
  3716. + AR71XX_USB_CTRL_SIZE);
  3717. +
  3718. + ar71xx_detect_mem_size();
  3719. + ar71xx_detect_sys_type();
  3720. + detect_sys_frequency();
  3721. +
  3722. + printk(KERN_INFO
  3723. + "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n",
  3724. + ar71xx_sys_type,
  3725. + ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000,
  3726. + ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000,
  3727. + ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000);
  3728. +
  3729. + _machine_restart = ar71xx_restart;
  3730. + _machine_halt = ar71xx_halt;
  3731. + pm_power_off = ar71xx_halt;
  3732. +
  3733. + board_be_handler = ar71xx_be_handler;
  3734. +
  3735. + ar71xx_early_serial_setup();
  3736. +}
  3737. +
  3738. +void __init plat_time_init(void)
  3739. +{
  3740. + mips_hpt_frequency = ar71xx_cpu_freq / 2;
  3741. +}
  3742. +
  3743. +static int __init ar71xx_machine_setup(void)
  3744. +{
  3745. + ar71xx_gpio_init();
  3746. +
  3747. + ar71xx_add_device_uart();
  3748. + ar71xx_add_device_wdt();
  3749. +
  3750. + mips_machine_setup(ar71xx_mach_type);
  3751. + return 0;
  3752. +}
  3753. +
  3754. +arch_initcall(ar71xx_machine_setup);
  3755. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.29.1/arch/mips/include/asm/fw/myloader/myloader.h
  3756. --- linux-2.6.29.1.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100
  3757. +++ linux-2.6.29.1/arch/mips/include/asm/fw/myloader/myloader.h 2009-04-13 14:27:34.599071210 +0200
  3758. @@ -0,0 +1,34 @@
  3759. +/*
  3760. + * Compex's MyLoader specific definitions
  3761. + *
  3762. + * Copyright (C) 2006-2008 Gabor Juhos <juhosg@openwrt.org>
  3763. + *
  3764. + * This program is free software; you can redistribute it and/or modify it
  3765. + * under the terms of the GNU General Public License version 2 as published
  3766. + * by the Free Software Foundation.
  3767. + *
  3768. + */
  3769. +
  3770. +#ifndef _ASM_MIPS_FW_MYLOADER_H
  3771. +#define _ASM_MIPS_FW_MYLOADER_H
  3772. +
  3773. +#include <linux/myloader.h>
  3774. +
  3775. +struct myloader_info {
  3776. + uint32_t vid;
  3777. + uint32_t did;
  3778. + uint32_t svid;
  3779. + uint32_t sdid;
  3780. + uint8_t macs[MYLO_ETHADDR_COUNT][6];
  3781. +};
  3782. +
  3783. +#ifdef CONFIG_MYLOADER
  3784. +extern struct myloader_info *myloader_get_info(void) __init;
  3785. +#else
  3786. +static inline struct myloader_info *myloader_get_info(void)
  3787. +{
  3788. + return NULL;
  3789. +}
  3790. +#endif /* CONFIG_MYLOADER */
  3791. +
  3792. +#endif /* _ASM_MIPS_FW_MYLOADER_H */
  3793. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/ar71xx.h
  3794. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100
  3795. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2009-04-13 14:27:34.623072313 +0200
  3796. @@ -0,0 +1,438 @@
  3797. +/*
  3798. + * Atheros AR71xx SoC specific definitions
  3799. + *
  3800. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3801. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3802. + *
  3803. + * Parts of this file are based on Atheros' 2.6.15 BSP
  3804. + *
  3805. + * This program is free software; you can redistribute it and/or modify it
  3806. + * under the terms of the GNU General Public License version 2 as published
  3807. + * by the Free Software Foundation.
  3808. + */
  3809. +
  3810. +#ifndef __ASM_MACH_AR71XX_H
  3811. +#define __ASM_MACH_AR71XX_H
  3812. +
  3813. +#include <linux/types.h>
  3814. +#include <linux/init.h>
  3815. +#include <linux/io.h>
  3816. +#include <linux/bitops.h>
  3817. +
  3818. +#ifndef __ASSEMBLER__
  3819. +
  3820. +#define AR71XX_PCI_MEM_BASE 0x10000000
  3821. +#define AR71XX_PCI_MEM_SIZE 0x08000000
  3822. +#define AR71XX_APB_BASE 0x18000000
  3823. +#define AR71XX_GE0_BASE 0x19000000
  3824. +#define AR71XX_GE0_SIZE 0x01000000
  3825. +#define AR71XX_GE1_BASE 0x1a000000
  3826. +#define AR71XX_GE1_SIZE 0x01000000
  3827. +#define AR71XX_EHCI_BASE 0x1b000000
  3828. +#define AR71XX_EHCI_SIZE 0x01000000
  3829. +#define AR71XX_OHCI_BASE 0x1c000000
  3830. +#define AR71XX_OHCI_SIZE 0x01000000
  3831. +#define AR71XX_SPI_BASE 0x1f000000
  3832. +#define AR71XX_SPI_SIZE 0x01000000
  3833. +
  3834. +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
  3835. +#define AR71XX_DDR_CTRL_SIZE 0x10000
  3836. +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
  3837. +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  3838. +#define AR71XX_UART_SIZE 0x10000
  3839. +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
  3840. +#define AR71XX_USB_CTRL_SIZE 0x10000
  3841. +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
  3842. +#define AR71XX_GPIO_SIZE 0x10000
  3843. +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
  3844. +#define AR71XX_PLL_SIZE 0x10000
  3845. +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
  3846. +#define AR71XX_RESET_SIZE 0x10000
  3847. +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
  3848. +#define AR71XX_MII_SIZE 0x10000
  3849. +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
  3850. +#define AR71XX_SLIC_SIZE 0x10000
  3851. +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
  3852. +#define AR71XX_DMA_SIZE 0x10000
  3853. +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
  3854. +#define AR71XX_STEREO_SIZE 0x10000
  3855. +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
  3856. +#define AR91XX_WMAC_SIZE 0x30000
  3857. +
  3858. +#define AR71XX_MEM_SIZE_MIN 0x0200000
  3859. +#define AR71XX_MEM_SIZE_MAX 0x8000000
  3860. +
  3861. +#define AR71XX_CPU_IRQ_BASE 0
  3862. +#define AR71XX_MISC_IRQ_BASE 8
  3863. +#define AR71XX_MISC_IRQ_COUNT 8
  3864. +#define AR71XX_GPIO_IRQ_BASE 16
  3865. +#define AR71XX_GPIO_IRQ_COUNT 16
  3866. +#define AR71XX_PCI_IRQ_BASE 32
  3867. +#define AR71XX_PCI_IRQ_COUNT 4
  3868. +
  3869. +#define AR71XX_CPU_IRQ_PCI (AR71XX_CPU_IRQ_BASE + 2)
  3870. +#define AR71XX_CPU_IRQ_WMAC (AR71XX_CPU_IRQ_BASE + 2)
  3871. +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
  3872. +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
  3873. +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
  3874. +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
  3875. +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
  3876. +
  3877. +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
  3878. +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
  3879. +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
  3880. +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
  3881. +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
  3882. +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
  3883. +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
  3884. +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
  3885. +
  3886. +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
  3887. +
  3888. +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
  3889. +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
  3890. +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
  3891. +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 3)
  3892. +
  3893. +extern u32 ar71xx_ahb_freq;
  3894. +extern u32 ar71xx_cpu_freq;
  3895. +extern u32 ar71xx_ddr_freq;
  3896. +
  3897. +enum ar71xx_soc_type {
  3898. + AR71XX_SOC_UNKNOWN,
  3899. + AR71XX_SOC_AR7130,
  3900. + AR71XX_SOC_AR7141,
  3901. + AR71XX_SOC_AR7161,
  3902. + AR71XX_SOC_AR9130,
  3903. + AR71XX_SOC_AR9132
  3904. +};
  3905. +
  3906. +extern enum ar71xx_soc_type ar71xx_soc;
  3907. +
  3908. +extern unsigned long ar71xx_mach_type;
  3909. +
  3910. +#define AR71XX_MACH_GENERIC 0
  3911. +#define AR71XX_MACH_WP543 1 /* Compex WP543 */
  3912. +#define AR71XX_MACH_RB_411 2 /* MikroTik RouterBOARD 411/411A/411AH */
  3913. +#define AR71XX_MACH_RB_433 3 /* MikroTik RouterBOARD 433/433AH */
  3914. +#define AR71XX_MACH_RB_450 4 /* MikroTik RouterBOARD 450 */
  3915. +#define AR71XX_MACH_RB_493 5 /* Mikrotik RouterBOARD 493/493AH */
  3916. +#define AR71XX_MACH_AW_NR580 6 /* AzureWave AW-NR580 */
  3917. +#define AR71XX_MACH_AP83 7 /* Atheros AP83 */
  3918. +#define AR71XX_MACH_TEW_632BRP 8 /* TRENDnet TEW-632BRP */
  3919. +#define AR71XX_MACH_UBNT_RS 9 /* Ubiquiti RouterStation */
  3920. +#define AR71XX_MACH_UBNT_LSX 10 /* Ubiquiti LSX */
  3921. +#define AR71XX_MACH_WNR2000 11 /* NETGEAR WNR2000 */
  3922. +#define AR71XX_MACH_PB42 12 /* Atheros PB42 */
  3923. +#define AR71XX_MACH_MZK_W300NH 13 /* Planex MZK-W300NH */
  3924. +#define AR71XX_MACH_MZK_W04NU 14 /* Planex MZK-W04NU */
  3925. +#define AR71XX_MACH_UBNT_LSSR71 15 /* Ubiquiti LS-SR71 */
  3926. +#define AR71XX_MACH_TL_WR941ND 16 /* TP-LINK TL-WR941ND */
  3927. +#define AR71XX_MACH_UBNT_RSPRO 17 /* Ubiquiti RouterStation Pro */
  3928. +#define AR71XX_MACH_AP81 18 /* Atheros AP81 */
  3929. +
  3930. +/*
  3931. + * PLL block
  3932. + */
  3933. +#define AR71XX_PLL_REG_CPU_CONFIG 0x00
  3934. +#define AR71XX_PLL_REG_SEC_CONFIG 0x04
  3935. +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
  3936. +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
  3937. +
  3938. +#define AR71XX_PLL_DIV_SHIFT 3
  3939. +#define AR71XX_PLL_DIV_MASK 0x1f
  3940. +#define AR71XX_CPU_DIV_SHIFT 16
  3941. +#define AR71XX_CPU_DIV_MASK 0x3
  3942. +#define AR71XX_DDR_DIV_SHIFT 18
  3943. +#define AR71XX_DDR_DIV_MASK 0x3
  3944. +#define AR71XX_AHB_DIV_SHIFT 20
  3945. +#define AR71XX_AHB_DIV_MASK 0x7
  3946. +
  3947. +#define AR71XX_ETH0_PLL_SHIFT 17
  3948. +#define AR71XX_ETH1_PLL_SHIFT 19
  3949. +
  3950. +#define AR91XX_PLL_REG_CPU_CONFIG 0x00
  3951. +#define AR91XX_PLL_REG_ETH_CONFIG 0x04
  3952. +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
  3953. +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
  3954. +
  3955. +#define AR91XX_PLL_DIV_SHIFT 0
  3956. +#define AR91XX_PLL_DIV_MASK 0x3ff
  3957. +#define AR91XX_DDR_DIV_SHIFT 22
  3958. +#define AR91XX_DDR_DIV_MASK 0x3
  3959. +#define AR91XX_AHB_DIV_SHIFT 19
  3960. +#define AR91XX_AHB_DIV_MASK 0x1
  3961. +
  3962. +#define AR91XX_ETH0_PLL_SHIFT 20
  3963. +#define AR91XX_ETH1_PLL_SHIFT 22
  3964. +
  3965. +extern void __iomem *ar71xx_pll_base;
  3966. +
  3967. +static inline void ar71xx_pll_wr(unsigned reg, u32 val)
  3968. +{
  3969. + __raw_writel(val, ar71xx_pll_base + reg);
  3970. +}
  3971. +
  3972. +static inline u32 ar71xx_pll_rr(unsigned reg)
  3973. +{
  3974. + return __raw_readl(ar71xx_pll_base + reg);
  3975. +}
  3976. +
  3977. +/*
  3978. + * USB_CONFIG block
  3979. + */
  3980. +#define USB_CTRL_REG_FLADJ 0x00
  3981. +#define USB_CTRL_REG_CONFIG 0x04
  3982. +
  3983. +extern void __iomem *ar71xx_usb_ctrl_base;
  3984. +
  3985. +static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
  3986. +{
  3987. + __raw_writel(val, ar71xx_usb_ctrl_base + reg);
  3988. +}
  3989. +
  3990. +static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
  3991. +{
  3992. + return __raw_readl(ar71xx_usb_ctrl_base + reg);
  3993. +}
  3994. +
  3995. +/*
  3996. + * GPIO block
  3997. + */
  3998. +#define GPIO_REG_OE 0x00
  3999. +#define GPIO_REG_IN 0x04
  4000. +#define GPIO_REG_OUT 0x08
  4001. +#define GPIO_REG_SET 0x0c
  4002. +#define GPIO_REG_CLEAR 0x10
  4003. +#define GPIO_REG_INT_MODE 0x14
  4004. +#define GPIO_REG_INT_TYPE 0x18
  4005. +#define GPIO_REG_INT_POLARITY 0x1c
  4006. +#define GPIO_REG_INT_PENDING 0x20
  4007. +#define GPIO_REG_INT_ENABLE 0x24
  4008. +#define GPIO_REG_FUNC 0x28
  4009. +
  4010. +#define GPIO_FUNC_STEREO_EN BIT(17)
  4011. +#define GPIO_FUNC_SLIC_EN BIT(16)
  4012. +#define GPIO_FUNC_SPI_CS2_EN BIT(13)
  4013. +#define GPIO_FUNC_SPI_CS1_EN BIT(12)
  4014. +#define GPIO_FUNC_UART_EN BIT(8)
  4015. +#define GPIO_FUNC_USB_OC_EN BIT(4)
  4016. +#define GPIO_FUNC_USB_CLK_EN BIT(0)
  4017. +
  4018. +#define AR71XX_GPIO_COUNT 16
  4019. +#define AR91XX_GPIO_COUNT 22
  4020. +
  4021. +extern void __iomem *ar71xx_gpio_base;
  4022. +
  4023. +static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
  4024. +{
  4025. + __raw_writel(value, ar71xx_gpio_base + reg);
  4026. +}
  4027. +
  4028. +static inline u32 ar71xx_gpio_rr(unsigned reg)
  4029. +{
  4030. + return __raw_readl(ar71xx_gpio_base + reg);
  4031. +}
  4032. +
  4033. +extern void ar71xx_gpio_init(void) __init;
  4034. +extern void ar71xx_gpio_function_enable(u32 mask);
  4035. +extern void ar71xx_gpio_function_disable(u32 mask);
  4036. +
  4037. +/*
  4038. + * DDR_CTRL block
  4039. + */
  4040. +#define AR71XX_DDR_REG_PCI_WIN0 0x7c
  4041. +#define AR71XX_DDR_REG_PCI_WIN1 0x80
  4042. +#define AR71XX_DDR_REG_PCI_WIN2 0x84
  4043. +#define AR71XX_DDR_REG_PCI_WIN3 0x88
  4044. +#define AR71XX_DDR_REG_PCI_WIN4 0x8c
  4045. +#define AR71XX_DDR_REG_PCI_WIN5 0x90
  4046. +#define AR71XX_DDR_REG_PCI_WIN6 0x94
  4047. +#define AR71XX_DDR_REG_PCI_WIN7 0x98
  4048. +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
  4049. +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
  4050. +#define AR71XX_DDR_REG_FLUSH_USB 0xa4
  4051. +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
  4052. +
  4053. +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
  4054. +#define AR91XX_DDR_REG_FLUSH_GE1 0x80
  4055. +#define AR91XX_DDR_REG_FLUSH_USB 0x84
  4056. +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
  4057. +
  4058. +#define PCI_WIN0_OFFS 0x10000000
  4059. +#define PCI_WIN1_OFFS 0x11000000
  4060. +#define PCI_WIN2_OFFS 0x12000000
  4061. +#define PCI_WIN3_OFFS 0x13000000
  4062. +#define PCI_WIN4_OFFS 0x14000000
  4063. +#define PCI_WIN5_OFFS 0x15000000
  4064. +#define PCI_WIN6_OFFS 0x16000000
  4065. +#define PCI_WIN7_OFFS 0x07000000
  4066. +
  4067. +extern void __iomem *ar71xx_ddr_base;
  4068. +
  4069. +static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
  4070. +{
  4071. + __raw_writel(val, ar71xx_ddr_base + reg);
  4072. +}
  4073. +
  4074. +static inline u32 ar71xx_ddr_rr(unsigned reg)
  4075. +{
  4076. + return __raw_readl(ar71xx_ddr_base + reg);
  4077. +}
  4078. +
  4079. +extern void ar71xx_ddr_flush(u32 reg);
  4080. +
  4081. +/*
  4082. + * PCI block
  4083. + */
  4084. +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
  4085. +#define AR71XX_PCI_CFG_SIZE 0x100
  4086. +
  4087. +#define PCI_REG_CRP_AD_CBE 0x00
  4088. +#define PCI_REG_CRP_WRDATA 0x04
  4089. +#define PCI_REG_CRP_RDDATA 0x08
  4090. +#define PCI_REG_CFG_AD 0x0c
  4091. +#define PCI_REG_CFG_CBE 0x10
  4092. +#define PCI_REG_CFG_WRDATA 0x14
  4093. +#define PCI_REG_CFG_RDDATA 0x18
  4094. +#define PCI_REG_PCI_ERR 0x1c
  4095. +#define PCI_REG_PCI_ERR_ADDR 0x20
  4096. +#define PCI_REG_AHB_ERR 0x24
  4097. +#define PCI_REG_AHB_ERR_ADDR 0x28
  4098. +
  4099. +#define PCI_CRP_CMD_WRITE 0x00010000
  4100. +#define PCI_CRP_CMD_READ 0x00000000
  4101. +#define PCI_CFG_CMD_READ 0x0000000a
  4102. +#define PCI_CFG_CMD_WRITE 0x0000000b
  4103. +
  4104. +#define PCI_IDSEL_ADL_START 17
  4105. +
  4106. +/*
  4107. + * RESET block
  4108. + */
  4109. +#define AR71XX_RESET_REG_TIMER 0x00
  4110. +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
  4111. +#define AR71XX_RESET_REG_WDOG_CTRL 0x08
  4112. +#define AR71XX_RESET_REG_WDOG 0x0c
  4113. +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
  4114. +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
  4115. +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
  4116. +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
  4117. +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
  4118. +#define AR71XX_RESET_REG_RESET_MODULE 0x24
  4119. +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
  4120. +#define AR71XX_RESET_REG_PERFC0 0x30
  4121. +#define AR71XX_RESET_REG_PERFC1 0x34
  4122. +#define AR71XX_RESET_REG_REV_ID 0x90
  4123. +
  4124. +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
  4125. +#define AR91XX_RESET_REG_RESET_MODULE 0x1c
  4126. +#define AR91XX_RESET_REG_PERF_CTRL 0x20
  4127. +#define AR91XX_RESET_REG_PERFC0 0x24
  4128. +#define AR91XX_RESET_REG_PERFC1 0x28
  4129. +
  4130. +#define WDOG_CTRL_LAST_RESET BIT(31)
  4131. +#define WDOG_CTRL_ACTION_MASK 3
  4132. +#define WDOG_CTRL_ACTION_NONE 0 /* no action */
  4133. +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
  4134. +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
  4135. +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
  4136. +
  4137. +#define MISC_INT_DMA BIT(7)
  4138. +#define MISC_INT_OHCI BIT(6)
  4139. +#define MISC_INT_PERFC BIT(5)
  4140. +#define MISC_INT_WDOG BIT(4)
  4141. +#define MISC_INT_UART BIT(3)
  4142. +#define MISC_INT_GPIO BIT(2)
  4143. +#define MISC_INT_ERROR BIT(1)
  4144. +#define MISC_INT_TIMER BIT(0)
  4145. +
  4146. +#define PCI_INT_CORE BIT(4)
  4147. +#define PCI_INT_DEV2 BIT(2)
  4148. +#define PCI_INT_DEV1 BIT(1)
  4149. +#define PCI_INT_DEV0 BIT(0)
  4150. +
  4151. +#define RESET_MODULE_EXTERNAL BIT(28)
  4152. +#define RESET_MODULE_FULL_CHIP BIT(24)
  4153. +#define RESET_MODULE_AMBA2WMAC BIT(22)
  4154. +#define RESET_MODULE_CPU_NMI BIT(21)
  4155. +#define RESET_MODULE_CPU_COLD BIT(20)
  4156. +#define RESET_MODULE_DMA BIT(19)
  4157. +#define RESET_MODULE_SLIC BIT(18)
  4158. +#define RESET_MODULE_STEREO BIT(17)
  4159. +#define RESET_MODULE_DDR BIT(16)
  4160. +#define RESET_MODULE_GE1_MAC BIT(13)
  4161. +#define RESET_MODULE_GE1_PHY BIT(12)
  4162. +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
  4163. +#define RESET_MODULE_GE0_MAC BIT(9)
  4164. +#define RESET_MODULE_GE0_PHY BIT(8)
  4165. +#define RESET_MODULE_USB_OHCI_DLL BIT(6)
  4166. +#define RESET_MODULE_USB_HOST BIT(5)
  4167. +#define RESET_MODULE_USB_PHY BIT(4)
  4168. +#define RESET_MODULE_PCI_BUS BIT(1)
  4169. +#define RESET_MODULE_PCI_CORE BIT(0)
  4170. +
  4171. +#define REV_ID_MASK 0xff
  4172. +#define REV_ID_CHIP_MASK 0xf3
  4173. +#define REV_ID_CHIP_AR7130 0xa0
  4174. +#define REV_ID_CHIP_AR7141 0xa1
  4175. +#define REV_ID_CHIP_AR7161 0xa2
  4176. +#define REV_ID_CHIP_AR9130 0xb0
  4177. +#define REV_ID_CHIP_AR9132 0xb1
  4178. +
  4179. +#define REV_ID_REVISION_MASK 0x3
  4180. +#define REV_ID_REVISION_SHIFT 2
  4181. +
  4182. +extern void __iomem *ar71xx_reset_base;
  4183. +
  4184. +static inline void ar71xx_reset_wr(unsigned reg, u32 val)
  4185. +{
  4186. + __raw_writel(val, ar71xx_reset_base + reg);
  4187. +}
  4188. +
  4189. +static inline u32 ar71xx_reset_rr(unsigned reg)
  4190. +{
  4191. + return __raw_readl(ar71xx_reset_base + reg);
  4192. +}
  4193. +
  4194. +extern void ar71xx_device_stop(u32 mask);
  4195. +extern void ar71xx_device_start(u32 mask);
  4196. +
  4197. +/*
  4198. + * SPI block
  4199. + */
  4200. +#define SPI_REG_FS 0x00 /* Function Select */
  4201. +#define SPI_REG_CTRL 0x04 /* SPI Control */
  4202. +#define SPI_REG_IOC 0x08 /* SPI I/O Control */
  4203. +#define SPI_REG_RDS 0x0c /* Read Data Shift */
  4204. +
  4205. +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
  4206. +
  4207. +#define SPI_CTRL_RD BIT(6) /* Remap Disable */
  4208. +#define SPI_CTRL_DIV_MASK 0x3f
  4209. +
  4210. +#define SPI_IOC_DO BIT(0) /* Data Out pin */
  4211. +#define SPI_IOC_CLK BIT(8) /* CLK pin */
  4212. +#define SPI_IOC_CS(n) BIT(16 + (n))
  4213. +#define SPI_IOC_CS0 SPI_IOC_CS(0)
  4214. +#define SPI_IOC_CS1 SPI_IOC_CS(1)
  4215. +#define SPI_IOC_CS2 SPI_IOC_CS(2)
  4216. +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
  4217. +
  4218. +/*
  4219. + * MII_CTRL block
  4220. + */
  4221. +#define MII_REG_MII0_CTRL 0x00
  4222. +#define MII_REG_MII1_CTRL 0x04
  4223. +
  4224. +#define MII0_CTRL_IF_GMII 0
  4225. +#define MII0_CTRL_IF_MII 1
  4226. +#define MII0_CTRL_IF_RGMII 2
  4227. +#define MII0_CTRL_IF_RMII 3
  4228. +
  4229. +#define MII1_CTRL_IF_RGMII 0
  4230. +#define MII1_CTRL_IF_RMII 1
  4231. +
  4232. +#endif /* __ASSEMBLER__ */
  4233. +
  4234. +#endif /* __ASM_MACH_AR71XX_H */
  4235. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h
  4236. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100
  4237. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2009-04-13 14:27:34.627073939 +0200
  4238. @@ -0,0 +1,56 @@
  4239. +/*
  4240. + * Atheros AR71xx specific CPU feature overrides
  4241. + *
  4242. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4243. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4244. + *
  4245. + * This file was derived from: include/asm-mips/cpu-features.h
  4246. + * Copyright (C) 2003, 2004 Ralf Baechle
  4247. + * Copyright (C) 2004 Maciej W. Rozycki
  4248. + *
  4249. + * This program is free software; you can redistribute it and/or modify it
  4250. + * under the terms of the GNU General Public License version 2 as published
  4251. + * by the Free Software Foundation.
  4252. + *
  4253. + */
  4254. +#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  4255. +#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  4256. +
  4257. +#define cpu_has_tlb 1
  4258. +#define cpu_has_4kex 1
  4259. +#define cpu_has_3k_cache 0
  4260. +#define cpu_has_4k_cache 1
  4261. +#define cpu_has_tx39_cache 0
  4262. +#define cpu_has_sb1_cache 0
  4263. +#define cpu_has_fpu 0
  4264. +#define cpu_has_32fpr 0
  4265. +#define cpu_has_counter 1
  4266. +#define cpu_has_watch 1
  4267. +#define cpu_has_divec 1
  4268. +
  4269. +#define cpu_has_prefetch 1
  4270. +#define cpu_has_ejtag 1
  4271. +#define cpu_has_llsc 1
  4272. +
  4273. +#define cpu_has_mips16 1
  4274. +#define cpu_has_mdmx 0
  4275. +#define cpu_has_mips3d 0
  4276. +#define cpu_has_smartmips 0
  4277. +
  4278. +#define cpu_has_mips32r1 1
  4279. +#define cpu_has_mips32r2 1
  4280. +#define cpu_has_mips64r1 0
  4281. +#define cpu_has_mips64r2 0
  4282. +
  4283. +#define cpu_has_dsp 0
  4284. +#define cpu_has_mipsmt 0
  4285. +
  4286. +#define cpu_has_64bits 0
  4287. +#define cpu_has_64bit_zero_reg 0
  4288. +#define cpu_has_64bit_gp_regs 0
  4289. +#define cpu_has_64bit_addresses 0
  4290. +
  4291. +#define cpu_dcache_line_size() 32
  4292. +#define cpu_icache_line_size() 32
  4293. +
  4294. +#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */
  4295. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/gpio.h
  4296. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100
  4297. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/gpio.h 2009-04-13 14:27:34.627073939 +0200
  4298. @@ -0,0 +1,53 @@
  4299. +/*
  4300. + * Atheros AR71xx GPIO API definitions
  4301. + *
  4302. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4303. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4304. + *
  4305. + * This program is free software; you can redistribute it and/or modify it
  4306. + * under the terms of the GNU General Public License version 2 as published
  4307. + * by the Free Software Foundation.
  4308. + *
  4309. + */
  4310. +
  4311. +#ifndef __ASM_MACH_AR71XX_GPIO_H
  4312. +#define __ASM_MACH_AR71XX_GPIO_H
  4313. +
  4314. +#define ARCH_NR_GPIOS 64
  4315. +#include <asm-generic/gpio.h>
  4316. +
  4317. +#include <asm/mach-ar71xx/ar71xx.h>
  4318. +
  4319. +extern unsigned long ar71xx_gpio_count;
  4320. +extern void __ar71xx_gpio_set_value(unsigned gpio, int value);
  4321. +extern int __ar71xx_gpio_get_value(unsigned gpio);
  4322. +
  4323. +static inline int gpio_to_irq(unsigned gpio)
  4324. +{
  4325. + return AR71XX_GPIO_IRQ(gpio);
  4326. +}
  4327. +
  4328. +static inline int irq_to_gpio(unsigned irq)
  4329. +{
  4330. + return irq - AR71XX_GPIO_IRQ_BASE;
  4331. +}
  4332. +
  4333. +static inline int gpio_get_value(unsigned gpio)
  4334. +{
  4335. + if (gpio < ar71xx_gpio_count)
  4336. + return __ar71xx_gpio_get_value(gpio);
  4337. +
  4338. + return __gpio_get_value(gpio);
  4339. +}
  4340. +
  4341. +static inline void gpio_set_value(unsigned gpio, int value)
  4342. +{
  4343. + if (gpio < ar71xx_gpio_count)
  4344. + __ar71xx_gpio_set_value(gpio, value);
  4345. + else
  4346. + __gpio_set_value(gpio, value);
  4347. +}
  4348. +
  4349. +#define gpio_cansleep __gpio_cansleep
  4350. +
  4351. +#endif /* __ASM_MACH_AR71XX_GPIO_H */
  4352. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/irq.h
  4353. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100
  4354. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/irq.h 2009-04-13 14:27:34.643075140 +0200
  4355. @@ -0,0 +1,17 @@
  4356. +/*
  4357. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4358. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4359. + *
  4360. + * This program is free software; you can redistribute it and/or modify it
  4361. + * under the terms of the GNU General Public License version 2 as published
  4362. + * by the Free Software Foundation.
  4363. + */
  4364. +#ifndef __ASM_MACH_AR71XX_IRQ_H
  4365. +#define __ASM_MACH_AR71XX_IRQ_H
  4366. +
  4367. +#define MIPS_CPU_IRQ_BASE 0
  4368. +#define NR_IRQS 36
  4369. +
  4370. +#include_next <irq.h>
  4371. +
  4372. +#endif /* __ASM_MACH_AR71XX_IRQ_H */
  4373. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h
  4374. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
  4375. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2009-04-13 14:27:34.643075140 +0200
  4376. @@ -0,0 +1,32 @@
  4377. +/*
  4378. + * Atheros AR71xx specific kernel entry setup
  4379. + *
  4380. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  4381. + *
  4382. + * This program is free software; you can redistribute it and/or modify it
  4383. + * under the terms of the GNU General Public License version 2 as published
  4384. + * by the Free Software Foundation.
  4385. + *
  4386. + */
  4387. +#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  4388. +#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  4389. +
  4390. + /*
  4391. + * Some bootloaders set the 'Kseg0 coherency algorithm' to
  4392. + * 'Cacheable, noncoherent, write-through, no write allocate'
  4393. + * and this cause performance issues. Let's go and change it to
  4394. + * 'Cacheable, noncoherent, write-back, write allocate'
  4395. + */
  4396. + .macro kernel_entry_setup
  4397. + mfc0 t0, CP0_CONFIG
  4398. + li t1, ~CONF_CM_CMASK
  4399. + and t0, t1
  4400. + ori t0, CONF_CM_CACHABLE_NONCOHERENT
  4401. + mtc0 t0, CP0_CONFIG
  4402. + nop
  4403. + .endm
  4404. +
  4405. + .macro smp_slave_setup
  4406. + .endm
  4407. +
  4408. +#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */
  4409. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/mangle-port.h
  4410. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100
  4411. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2009-04-13 14:27:34.643075140 +0200
  4412. @@ -0,0 +1,45 @@
  4413. +/*
  4414. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4415. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4416. + *
  4417. + * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
  4418. + * Copyright (C) 2003, 2004 Ralf Baechle
  4419. + *
  4420. + * This program is free software; you can redistribute it and/or modify it
  4421. + * under the terms of the GNU General Public License version 2 as published
  4422. + * by the Free Software Foundation.
  4423. + */
  4424. +
  4425. +#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H
  4426. +#define __ASM_MACH_AR71XX_MANGLE_PORT_H
  4427. +
  4428. +#define __swizzle_addr_b(port) ((port) ^ 3)
  4429. +#define __swizzle_addr_w(port) ((port) ^ 2)
  4430. +#define __swizzle_addr_l(port) (port)
  4431. +#define __swizzle_addr_q(port) (port)
  4432. +
  4433. +#if defined(CONFIG_SWAP_IO_SPACE)
  4434. +
  4435. +# define ioswabb(a, x) (x)
  4436. +# define __mem_ioswabb(a, x) (x)
  4437. +# define ioswabw(a, x) le16_to_cpu(x)
  4438. +# define __mem_ioswabw(a, x) (x)
  4439. +# define ioswabl(a, x) le32_to_cpu(x)
  4440. +# define __mem_ioswabl(a, x) (x)
  4441. +# define ioswabq(a, x) le64_to_cpu(x)
  4442. +# define __mem_ioswabq(a, x) (x)
  4443. +
  4444. +#else
  4445. +
  4446. +# define ioswabb(a, x) (x)
  4447. +# define __mem_ioswabb(a, x) (x)
  4448. +# define ioswabw(a, x) (x)
  4449. +# define __mem_ioswabw(a, x) cpu_to_le16(x)
  4450. +# define ioswabl(a, x) (x)
  4451. +# define __mem_ioswabl(a, x) cpu_to_le32(x)
  4452. +# define ioswabq(a, x) (x)
  4453. +# define __mem_ioswabq(a, x) cpu_to_le64(x)
  4454. +
  4455. +#endif
  4456. +
  4457. +#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */
  4458. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/pci.h
  4459. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100
  4460. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/pci.h 2009-04-13 14:27:34.647074532 +0200
  4461. @@ -0,0 +1,28 @@
  4462. +/*
  4463. + * Atheros AR71xx SoC specific PCI definitions
  4464. + *
  4465. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4466. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4467. + *
  4468. + * This program is free software; you can redistribute it and/or modify it
  4469. + * under the terms of the GNU General Public License version 2 as published
  4470. + * by the Free Software Foundation.
  4471. + */
  4472. +
  4473. +#ifndef __ASM_MACH_AR71XX_PCI_H
  4474. +#define __ASM_MACH_AR71XX_PCI_H
  4475. +
  4476. +struct ar71xx_pci_irq {
  4477. + int irq;
  4478. + u8 slot;
  4479. + u8 pin;
  4480. +};
  4481. +
  4482. +extern int (*ar71xx_pci_be_handler)(int is_fixup);
  4483. +extern int (*ar71xx_pci_bios_init)(unsigned nr_irqs,
  4484. + struct ar71xx_pci_irq *map) __initdata;
  4485. +
  4486. +extern int ar71xx_pci_init(unsigned nr_irqs,
  4487. + struct ar71xx_pci_irq *map) __init;
  4488. +
  4489. +#endif /* __ASM_MACH_AR71XX_PCI_H */
  4490. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/platform.h
  4491. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100
  4492. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/platform.h 2009-04-13 14:27:34.647074532 +0200
  4493. @@ -0,0 +1,54 @@
  4494. +/*
  4495. + * Atheros AR71xx SoC specific platform data definitions
  4496. + *
  4497. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4498. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4499. + *
  4500. + * This program is free software; you can redistribute it and/or modify it
  4501. + * under the terms of the GNU General Public License version 2 as published
  4502. + * by the Free Software Foundation.
  4503. + */
  4504. +
  4505. +#ifndef __ASM_MACH_AR71XX_PLATFORM_H
  4506. +#define __ASM_MACH_AR71XX_PLATFORM_H
  4507. +
  4508. +#include <linux/if_ether.h>
  4509. +#include <linux/skbuff.h>
  4510. +#include <linux/phy.h>
  4511. +#include <linux/spi/spi.h>
  4512. +
  4513. +struct ag71xx_platform_data {
  4514. + phy_interface_t phy_if_mode;
  4515. + u32 phy_mask;
  4516. + int speed;
  4517. + int duplex;
  4518. + u32 reset_bit;
  4519. + u32 mii_if;
  4520. + u8 mac_addr[ETH_ALEN];
  4521. +
  4522. + u8 has_gbit:1;
  4523. + u8 is_ar91xx:1;
  4524. + u8 has_ar8216:1;
  4525. +
  4526. + void (* ddr_flush)(void);
  4527. + void (* set_pll)(u32 pll);
  4528. +};
  4529. +
  4530. +struct ag71xx_mdio_platform_data {
  4531. + u32 phy_mask;
  4532. +};
  4533. +
  4534. +struct ar71xx_ehci_platform_data {
  4535. + u8 is_ar91xx;
  4536. +};
  4537. +
  4538. +struct ar71xx_spi_platform_data {
  4539. + unsigned bus_num;
  4540. + unsigned num_chipselect;
  4541. + u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on);
  4542. +};
  4543. +
  4544. +#define AR71XX_SPI_CS_INACTIVE 0
  4545. +#define AR71XX_SPI_CS_ACTIVE 1
  4546. +
  4547. +#endif /* __ASM_MACH_AR71XX_PLATFORM_H */
  4548. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/war.h
  4549. --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100
  4550. +++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/war.h 2009-04-13 14:27:34.647074532 +0200
  4551. @@ -0,0 +1,25 @@
  4552. +/*
  4553. + * This file is subject to the terms and conditions of the GNU General Public
  4554. + * License. See the file "COPYING" in the main directory of this archive
  4555. + * for more details.
  4556. + *
  4557. + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  4558. + */
  4559. +#ifndef __ASM_MACH_AR71XX_WAR_H
  4560. +#define __ASM_MACH_AR71XX_WAR_H
  4561. +
  4562. +#define R4600_V1_INDEX_ICACHEOP_WAR 0
  4563. +#define R4600_V1_HIT_CACHEOP_WAR 0
  4564. +#define R4600_V2_HIT_CACHEOP_WAR 0
  4565. +#define R5432_CP0_INTERRUPT_WAR 0
  4566. +#define BCM1250_M3_WAR 0
  4567. +#define SIBYTE_1956_WAR 0
  4568. +#define MIPS4K_ICACHE_REFILL_WAR 0
  4569. +#define MIPS_CACHE_SYNC_WAR 0
  4570. +#define TX49XX_ICACHE_INDEX_INV_WAR 0
  4571. +#define RM9000_CDEX_SMP_WAR 0
  4572. +#define ICACHE_REFILLS_WORKAROUND_WAR 0
  4573. +#define R10000_LLSC_WAR 0
  4574. +#define MIPS34K_MISSED_ITLB_WAR 0
  4575. +
  4576. +#endif /* __ASM_MACH_AR71XX_WAR_H */
  4577. diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/time.h linux-2.6.29.1/arch/mips/include/asm/time.h
  4578. --- linux-2.6.29.1.orig/arch/mips/include/asm/time.h 2009-04-02 22:55:27.000000000 +0200
  4579. +++ linux-2.6.29.1/arch/mips/include/asm/time.h 2009-04-13 14:30:23.269613602 +0200
  4580. @@ -52,6 +52,7 @@
  4581. */
  4582. #ifdef CONFIG_CEVT_R4K_LIB
  4583. extern unsigned int __weak get_c0_compare_int(void);
  4584. +extern unsigned int __weak get_c0_compare_irq(void);
  4585. extern int r4k_clockevent_init(void);
  4586. #endif
  4587. diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/Makefile linux-2.6.29.1/arch/mips/kernel/Makefile
  4588. --- linux-2.6.29.1.orig/arch/mips/kernel/Makefile 2009-04-02 22:55:27.000000000 +0200
  4589. +++ linux-2.6.29.1/arch/mips/kernel/Makefile 2009-04-13 14:27:34.655074992 +0200
  4590. @@ -85,6 +85,7 @@
  4591. obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
  4592. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  4593. +obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
  4594. CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
  4595. diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/cevt-r4k.c linux-2.6.29.1/arch/mips/kernel/cevt-r4k.c
  4596. --- linux-2.6.29.1.orig/arch/mips/kernel/cevt-r4k.c 2009-04-02 22:55:27.000000000 +0200
  4597. +++ linux-2.6.29.1/arch/mips/kernel/cevt-r4k.c 2009-04-13 14:27:34.655074992 +0200
  4598. @@ -15,6 +15,22 @@
  4599. #include <asm/cevt-r4k.h>
  4600. /*
  4601. + * Compare interrupt can be routed and latched outside the core,
  4602. + * so a single execution hazard barrier may not be enough to give
  4603. + * it time to clear as seen in the Cause register. 4 time the
  4604. + * pipeline depth seems reasonably conservative, and empirically
  4605. + * works better in configurations with high CPU/bus clock ratios.
  4606. + */
  4607. +
  4608. +#define compare_change_hazard() \
  4609. + do { \
  4610. + irq_disable_hazard(); \
  4611. + irq_disable_hazard(); \
  4612. + irq_disable_hazard(); \
  4613. + irq_disable_hazard(); \
  4614. + } while (0)
  4615. +
  4616. +/*
  4617. * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
  4618. * of these routines with SMTC-specific variants.
  4619. */
  4620. @@ -30,6 +46,7 @@
  4621. cnt = read_c0_count();
  4622. cnt += delta;
  4623. write_c0_compare(cnt);
  4624. + compare_change_hazard();
  4625. res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
  4626. return res;
  4627. }
  4628. @@ -99,22 +116,6 @@
  4629. return (read_c0_cause() >> cp0_compare_irq) & 0x100;
  4630. }
  4631. -/*
  4632. - * Compare interrupt can be routed and latched outside the core,
  4633. - * so a single execution hazard barrier may not be enough to give
  4634. - * it time to clear as seen in the Cause register. 4 time the
  4635. - * pipeline depth seems reasonably conservative, and empirically
  4636. - * works better in configurations with high CPU/bus clock ratios.
  4637. - */
  4638. -
  4639. -#define compare_change_hazard() \
  4640. - do { \
  4641. - irq_disable_hazard(); \
  4642. - irq_disable_hazard(); \
  4643. - irq_disable_hazard(); \
  4644. - irq_disable_hazard(); \
  4645. - } while (0)
  4646. -
  4647. int c0_compare_int_usable(void)
  4648. {
  4649. unsigned int delta;
  4650. diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/mips_machine.c linux-2.6.29.1/arch/mips/kernel/mips_machine.c
  4651. --- linux-2.6.29.1.orig/arch/mips/kernel/mips_machine.c 1970-01-01 01:00:00.000000000 +0100
  4652. +++ linux-2.6.29.1/arch/mips/kernel/mips_machine.c 2009-04-13 14:27:34.683076044 +0200
  4653. @@ -0,0 +1,58 @@
  4654. +/*
  4655. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4656. + *
  4657. + * This program is free software; you can redistribute it and/or modify it
  4658. + * under the terms of the GNU General Public License version 2 as published
  4659. + * by the Free Software Foundation.
  4660. + *
  4661. + */
  4662. +
  4663. +#include <asm/mips_machine.h>
  4664. +#include <asm/bootinfo.h>
  4665. +
  4666. +static struct list_head mips_machines __initdata =
  4667. + LIST_HEAD_INIT(mips_machines);
  4668. +
  4669. +unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN] = "Unknown";
  4670. +
  4671. +static struct mips_machine * __init mips_machine_find(unsigned long machtype)
  4672. +{
  4673. + struct list_head *this;
  4674. +
  4675. + list_for_each(this, &mips_machines) {
  4676. + struct mips_machine *mach;
  4677. +
  4678. + mach = list_entry(this, struct mips_machine, list);
  4679. + if (mach->mach_type == machtype)
  4680. + return mach;
  4681. + }
  4682. +
  4683. + return NULL;
  4684. +}
  4685. +
  4686. +void __init mips_machine_register(struct mips_machine *mach)
  4687. +{
  4688. + list_add_tail(&mach->list, &mips_machines);
  4689. +}
  4690. +
  4691. +void __init mips_machine_setup(unsigned long machtype)
  4692. +{
  4693. + struct mips_machine *mach;
  4694. +
  4695. + mach = mips_machine_find(machtype);
  4696. + if (!mach) {
  4697. + printk(KERN_ALERT "MIPS: no machine registered for "
  4698. + "machtype %lu\n", machtype);
  4699. + return;
  4700. + }
  4701. +
  4702. + if (mach->mach_name[0])
  4703. + strncpy(mips_machine_name, mach->mach_name,
  4704. + MIPS_MACHINE_NAME_LEN);
  4705. +
  4706. + printk(KERN_INFO "MIPS: machine is %s\n", mips_machine_name);
  4707. +
  4708. + if (mach->mach_setup)
  4709. + mach->mach_setup();
  4710. +}
  4711. +
  4712. diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/proc.c linux-2.6.29.1/arch/mips/kernel/proc.c
  4713. --- linux-2.6.29.1.orig/arch/mips/kernel/proc.c 2009-04-02 22:55:27.000000000 +0200
  4714. +++ linux-2.6.29.1/arch/mips/kernel/proc.c 2009-04-13 14:27:34.683076044 +0200
  4715. @@ -14,6 +14,7 @@
  4716. #include <asm/cpu-features.h>
  4717. #include <asm/mipsregs.h>
  4718. #include <asm/processor.h>
  4719. +#include <asm/mips_machine.h>
  4720. unsigned int vced_count, vcei_count;
  4721. @@ -33,8 +34,12 @@
  4722. /*
  4723. * For the first processor also print the system type
  4724. */
  4725. - if (n == 0)
  4726. + if (n == 0) {
  4727. seq_printf(m, "system type\t\t: %s\n", get_system_type());
  4728. +#ifdef CONFIG_MIPS_MACHINE
  4729. + seq_printf(m, "machine\t\t\t: %s\n", mips_machine_name);
  4730. +#endif
  4731. + }
  4732. seq_printf(m, "processor\t\t: %ld\n", n);
  4733. sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
  4734. diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/traps.c linux-2.6.29.1/arch/mips/kernel/traps.c
  4735. --- linux-2.6.29.1.orig/arch/mips/kernel/traps.c 2009-04-02 22:55:27.000000000 +0200
  4736. +++ linux-2.6.29.1/arch/mips/kernel/traps.c 2009-04-13 14:29:45.479250639 +0200
  4737. @@ -47,6 +47,7 @@
  4738. #include <asm/mmu_context.h>
  4739. #include <asm/types.h>
  4740. #include <asm/stacktrace.h>
  4741. +#include <asm/time.h>
  4742. #include <asm/irq.h>
  4743. extern void check_wait(void);
  4744. @@ -1541,6 +1542,8 @@
  4745. */
  4746. if (cpu_has_mips_r2) {
  4747. cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
  4748. + if (get_c0_compare_irq)
  4749. + cp0_compare_irq = get_c0_compare_irq();
  4750. cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
  4751. if (cp0_perfcount_irq == cp0_compare_irq)
  4752. cp0_perfcount_irq = -1;
  4753. diff -Nur linux-2.6.29.1.orig/arch/mips/pci/Makefile linux-2.6.29.1/arch/mips/pci/Makefile
  4754. --- linux-2.6.29.1.orig/arch/mips/pci/Makefile 2009-04-02 22:55:27.000000000 +0200
  4755. +++ linux-2.6.29.1/arch/mips/pci/Makefile 2009-04-13 14:27:34.691076784 +0200
  4756. @@ -16,6 +16,7 @@
  4757. obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
  4758. obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
  4759. obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
  4760. +obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o
  4761. #
  4762. # These are still pretty much in the old state, watch, go blind.
  4763. diff -Nur linux-2.6.29.1.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.29.1/arch/mips/pci/pci-ar71xx.c
  4764. --- linux-2.6.29.1.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  4765. +++ linux-2.6.29.1/arch/mips/pci/pci-ar71xx.c 2009-04-13 14:27:34.695077573 +0200
  4766. @@ -0,0 +1,347 @@
  4767. +/*
  4768. + * Atheros AR71xx PCI host controller driver
  4769. + *
  4770. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4771. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4772. + *
  4773. + * Parts of this file are based on Atheros' 2.6.15 BSP
  4774. + *
  4775. + * This program is free software; you can redistribute it and/or modify it
  4776. + * under the terms of the GNU General Public License version 2 as published
  4777. + * by the Free Software Foundation.
  4778. + */
  4779. +
  4780. +#include <linux/resource.h>
  4781. +#include <linux/types.h>
  4782. +#include <linux/delay.h>
  4783. +#include <linux/bitops.h>
  4784. +#include <linux/pci.h>
  4785. +#include <linux/pci_regs.h>
  4786. +
  4787. +#include <asm/mach-ar71xx/ar71xx.h>
  4788. +#include <asm/mach-ar71xx/pci.h>
  4789. +
  4790. +#undef DEBUG
  4791. +#ifdef DEBUG
  4792. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  4793. +#else
  4794. +#define DBG(fmt, args...)
  4795. +#endif
  4796. +
  4797. +#define AR71XX_PCI_DELAY 100 /* msecs */
  4798. +
  4799. +#if 0
  4800. +#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START
  4801. +#else
  4802. +#define PCI_IDSEL_BASE 0
  4803. +#endif
  4804. +
  4805. +static unsigned ar71xx_pci_nr_irqs;
  4806. +static struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  4807. +static void __iomem *ar71xx_pcicfg_base;
  4808. +
  4809. +static DEFINE_SPINLOCK(ar71xx_pci_lock);
  4810. +
  4811. +static inline void ar71xx_pci_delay(void)
  4812. +{
  4813. + mdelay(AR71XX_PCI_DELAY);
  4814. +}
  4815. +
  4816. +static inline u32 ar71xx_pcicfg_rr(unsigned int reg)
  4817. +{
  4818. + return __raw_readl(ar71xx_pcicfg_base + reg);
  4819. +}
  4820. +
  4821. +static inline void ar71xx_pcicfg_wr(unsigned int reg, u32 val)
  4822. +{
  4823. + __raw_writel(val, ar71xx_pcicfg_base + reg);
  4824. +}
  4825. +
  4826. +/* Byte lane enable bits */
  4827. +static u8 ble_table[4][4] = {
  4828. + {0x0, 0xf, 0xf, 0xf},
  4829. + {0xe, 0xd, 0xb, 0x7},
  4830. + {0xc, 0xf, 0x3, 0xf},
  4831. + {0xf, 0xf, 0xf, 0xf},
  4832. +};
  4833. +
  4834. +static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
  4835. +{
  4836. + u32 t;
  4837. +
  4838. + t = ble_table[size & 3][where & 3];
  4839. + BUG_ON(t == 0xf);
  4840. + t <<= (local) ? 20 : 4;
  4841. + return t;
  4842. +}
  4843. +
  4844. +static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
  4845. + int where)
  4846. +{
  4847. + u32 ret;
  4848. +
  4849. + if (!bus->number) {
  4850. + /* type 0 */
  4851. + ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn)))
  4852. + | (PCI_FUNC(devfn) << 8) | (where & ~3);
  4853. + } else {
  4854. + /* type 1 */
  4855. + ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11)
  4856. + | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
  4857. + }
  4858. +
  4859. + return ret;
  4860. +}
  4861. +
  4862. +static int __ar71xx_pci_be_handler(int is_fixup)
  4863. +{
  4864. + u32 pci_err;
  4865. + u32 ahb_err;
  4866. +
  4867. + pci_err = ar71xx_pcicfg_rr(PCI_REG_PCI_ERR) & 3;
  4868. + if (pci_err) {
  4869. + if (!is_fixup)
  4870. + printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n",
  4871. + pci_err,
  4872. + ar71xx_pcicfg_rr(PCI_REG_PCI_ERR_ADDR));
  4873. +
  4874. + ar71xx_pcicfg_wr(PCI_REG_PCI_ERR, pci_err);
  4875. + }
  4876. +
  4877. + ahb_err = ar71xx_pcicfg_rr(PCI_REG_AHB_ERR) & 1;
  4878. + if (ahb_err) {
  4879. + if (!is_fixup)
  4880. + printk(KERN_ALERT "AHB error at AHB address 0x%x\n",
  4881. + ar71xx_pcicfg_rr(PCI_REG_AHB_ERR_ADDR));
  4882. +
  4883. + ar71xx_pcicfg_wr(PCI_REG_AHB_ERR, ahb_err);
  4884. + }
  4885. +
  4886. + return ((ahb_err | pci_err) ? 1 : 0);
  4887. +}
  4888. +
  4889. +static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
  4890. + unsigned int devfn, int where, int size, u32 cmd)
  4891. +{
  4892. + u32 addr;
  4893. +
  4894. + addr = ar71xx_pci_bus_addr(bus, devfn, where);
  4895. +
  4896. + DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n",
  4897. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  4898. + where, size, addr);
  4899. +
  4900. + ar71xx_pcicfg_wr(PCI_REG_CFG_AD, addr);
  4901. + ar71xx_pcicfg_wr(PCI_REG_CFG_CBE,
  4902. + cmd | ar71xx_pci_get_ble(where, size, 0));
  4903. +
  4904. + return __ar71xx_pci_be_handler(1);
  4905. +}
  4906. +
  4907. +static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  4908. + int where, int size, u32 *value)
  4909. +{
  4910. + static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
  4911. + unsigned long flags;
  4912. + u32 data;
  4913. + int ret;
  4914. +
  4915. + ret = PCIBIOS_SUCCESSFUL;
  4916. +
  4917. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number,
  4918. + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
  4919. +
  4920. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  4921. +
  4922. + if (bus->number == 0 && devfn == 0) {
  4923. + u32 t;
  4924. +
  4925. + t = PCI_CRP_CMD_READ | (where & ~3);
  4926. +
  4927. + ar71xx_pcicfg_wr(PCI_REG_CRP_AD_CBE, t);
  4928. + data = ar71xx_pcicfg_rr(PCI_REG_CRP_RDDATA);
  4929. +
  4930. + DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data);
  4931. +
  4932. + } else {
  4933. + int err;
  4934. +
  4935. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  4936. + PCI_CFG_CMD_READ);
  4937. +
  4938. + if (err == 0) {
  4939. + data = ar71xx_pcicfg_rr(PCI_REG_CFG_RDDATA);
  4940. + } else {
  4941. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  4942. + data = ~0;
  4943. + }
  4944. + }
  4945. +
  4946. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  4947. +
  4948. + DBG("PCI: read config: data=%08x raw=%08x\n",
  4949. + (data >> (8 * (where & 3))) & mask[size & 7], data);
  4950. +
  4951. + *value = (data >> (8 * (where & 3))) & mask[size & 7];
  4952. +
  4953. + return ret;
  4954. +}
  4955. +
  4956. +static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  4957. + int where, int size, u32 value)
  4958. +{
  4959. + unsigned long flags;
  4960. + int ret;
  4961. +
  4962. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n",
  4963. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  4964. + where, size, value);
  4965. +
  4966. + value = value << (8 * (where & 3));
  4967. + ret = PCIBIOS_SUCCESSFUL;
  4968. +
  4969. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  4970. + if (bus->number == 0 && devfn == 0) {
  4971. + u32 t;
  4972. +
  4973. + t = PCI_CRP_CMD_WRITE | (where & ~3);
  4974. + t |= ar71xx_pci_get_ble(where, size, 1);
  4975. +
  4976. + DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value);
  4977. +
  4978. + ar71xx_pcicfg_wr(PCI_REG_CRP_AD_CBE, t);
  4979. + ar71xx_pcicfg_wr(PCI_REG_CRP_WRDATA, value);
  4980. + } else {
  4981. + int err;
  4982. +
  4983. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  4984. + PCI_CFG_CMD_WRITE);
  4985. +
  4986. + if (err == 0)
  4987. + ar71xx_pcicfg_wr(PCI_REG_CFG_WRDATA, value);
  4988. + else
  4989. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  4990. + }
  4991. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  4992. +
  4993. + return ret;
  4994. +}
  4995. +
  4996. +static void ar71xx_pci_fixup(struct pci_dev *dev)
  4997. +{
  4998. + u32 t;
  4999. +
  5000. + if (dev->bus->number != 0 || dev->devfn != 0)
  5001. + return;
  5002. +
  5003. + DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev),
  5004. + dev->vendor, dev->device);
  5005. +
  5006. + /* setup COMMAND register */
  5007. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
  5008. + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
  5009. +
  5010. + pci_write_config_word(dev, PCI_COMMAND, t);
  5011. +}
  5012. +
  5013. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup);
  5014. +
  5015. +int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
  5016. +{
  5017. + int irq = -1;
  5018. + int i;
  5019. +
  5020. + slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE;
  5021. +
  5022. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  5023. + struct ar71xx_pci_irq *entry;
  5024. +
  5025. + entry = &ar71xx_pci_irq_map[i];
  5026. + if (entry->slot == slot && entry->pin == pin) {
  5027. + irq = entry->irq;
  5028. + break;
  5029. + }
  5030. + }
  5031. +
  5032. + if (irq < 0) {
  5033. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  5034. + pin, pci_name((struct pci_dev *)dev));
  5035. + } else {
  5036. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  5037. + irq, pin, pci_name((struct pci_dev *)dev));
  5038. + }
  5039. +
  5040. + return irq;
  5041. +}
  5042. +
  5043. +int pcibios_plat_dev_init(struct pci_dev *dev)
  5044. +{
  5045. + return 0;
  5046. +}
  5047. +
  5048. +static struct pci_ops ar71xx_pci_ops = {
  5049. + .read = ar71xx_pci_read_config,
  5050. + .write = ar71xx_pci_write_config,
  5051. +};
  5052. +
  5053. +static struct resource ar71xx_pci_io_resource = {
  5054. + .name = "PCI IO space",
  5055. + .start = 0,
  5056. + .end = 0,
  5057. + .flags = IORESOURCE_IO,
  5058. +};
  5059. +
  5060. +static struct resource ar71xx_pci_mem_resource = {
  5061. + .name = "PCI memory space",
  5062. + .start = AR71XX_PCI_MEM_BASE,
  5063. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  5064. + .flags = IORESOURCE_MEM
  5065. +};
  5066. +
  5067. +static struct pci_controller ar71xx_pci_controller = {
  5068. + .pci_ops = &ar71xx_pci_ops,
  5069. + .mem_resource = &ar71xx_pci_mem_resource,
  5070. + .io_resource = &ar71xx_pci_io_resource,
  5071. +};
  5072. +
  5073. +static int __init __ar71xx_pci_bios_init(unsigned nr_irqs,
  5074. + struct ar71xx_pci_irq *map)
  5075. +{
  5076. + ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  5077. + ar71xx_pci_delay();
  5078. +
  5079. + ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  5080. + ar71xx_pci_delay();
  5081. +
  5082. + ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE,
  5083. + AR71XX_PCI_CFG_SIZE);
  5084. +
  5085. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN0, PCI_WIN0_OFFS);
  5086. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN1, PCI_WIN1_OFFS);
  5087. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN2, PCI_WIN2_OFFS);
  5088. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN3, PCI_WIN3_OFFS);
  5089. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN4, PCI_WIN4_OFFS);
  5090. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN5, PCI_WIN5_OFFS);
  5091. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN6, PCI_WIN6_OFFS);
  5092. + ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN7, PCI_WIN7_OFFS);
  5093. +
  5094. + ar71xx_pci_delay();
  5095. +
  5096. + /* clear bus errors */
  5097. + (void)__ar71xx_pci_be_handler(1);
  5098. +
  5099. + ar71xx_pci_nr_irqs = nr_irqs;
  5100. + ar71xx_pci_irq_map = map;
  5101. + ar71xx_pci_be_handler = __ar71xx_pci_be_handler;
  5102. +
  5103. + register_pci_controller(&ar71xx_pci_controller);
  5104. +
  5105. + return 0;
  5106. +}
  5107. +
  5108. +static int __init __ar71xx_pci_init(void)
  5109. +{
  5110. + ar71xx_pci_bios_init = __ar71xx_pci_bios_init;
  5111. + return 0;
  5112. +}
  5113. +pure_initcall(__ar71xx_pci_init);
  5114. diff -Nur linux-2.6.29.1.orig/drivers/input/misc/Kconfig linux-2.6.29.1/drivers/input/misc/Kconfig
  5115. --- linux-2.6.29.1.orig/drivers/input/misc/Kconfig 2009-04-02 22:55:27.000000000 +0200
  5116. +++ linux-2.6.29.1/drivers/input/misc/Kconfig 2009-04-13 14:27:34.723078345 +0200
  5117. @@ -227,4 +227,20 @@
  5118. Say Y to include support for delivering PMU events via input
  5119. layer on NXP PCF50633.
  5120. +config INPUT_GPIO_BUTTONS
  5121. + tristate "Polled GPIO buttons interface"
  5122. + depends on GENERIC_GPIO
  5123. + select INPUT_POLLDEV
  5124. + help
  5125. + This driver implements support for buttons connected
  5126. + to GPIO pins of various CPUs (and some other chips).
  5127. +
  5128. + Say Y here if your device has buttons connected
  5129. + directly to such GPIO pins. Your board-specific
  5130. + setup logic must also provide a platform device,
  5131. + with configuration data saying which GPIOs are used.
  5132. +
  5133. + To compile this driver as a module, choose M here: the
  5134. + module will be called gpio-buttons.
  5135. +
  5136. endif
  5137. diff -Nur linux-2.6.29.1.orig/drivers/input/misc/Makefile linux-2.6.29.1/drivers/input/misc/Makefile
  5138. --- linux-2.6.29.1.orig/drivers/input/misc/Makefile 2009-04-02 22:55:27.000000000 +0200
  5139. +++ linux-2.6.29.1/drivers/input/misc/Makefile 2009-04-13 14:29:03.564632184 +0200
  5140. @@ -22,3 +22,4 @@
  5141. obj-$(CONFIG_INPUT_APANEL) += apanel.o
  5142. obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
  5143. obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
  5144. +obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o
  5145. diff -Nur linux-2.6.29.1.orig/drivers/input/misc/gpio_buttons.c linux-2.6.29.1/drivers/input/misc/gpio_buttons.c
  5146. --- linux-2.6.29.1.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100
  5147. +++ linux-2.6.29.1/drivers/input/misc/gpio_buttons.c 2009-04-13 14:27:34.727079413 +0200
  5148. @@ -0,0 +1,209 @@
  5149. +/*
  5150. + * Driver for buttons on GPIO lines not capable of generating interrupts
  5151. + *
  5152. + * Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org>
  5153. + *
  5154. + * This file was based on: /drivers/input/misc/cobalt_btns.c
  5155. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  5156. + *
  5157. + * also was based on: /drivers/input/keyboard/gpio_keys.c
  5158. + * Copyright 2005 Phil Blundell
  5159. + *
  5160. + * This program is free software; you can redistribute it and/or modify
  5161. + * it under the terms of the GNU General Public License version 2 as
  5162. + * published by the Free Software Foundation.
  5163. + *
  5164. + */
  5165. +
  5166. +#include <linux/kernel.h>
  5167. +#include <linux/module.h>
  5168. +#include <linux/init.h>
  5169. +
  5170. +#include <linux/input.h>
  5171. +#include <linux/input-polldev.h>
  5172. +#include <linux/ioport.h>
  5173. +#include <linux/platform_device.h>
  5174. +
  5175. +#include <linux/gpio_buttons.h>
  5176. +
  5177. +#include <asm/gpio.h>
  5178. +
  5179. +#define DRV_NAME "gpio-buttons"
  5180. +#define DRV_VERSION "0.1.1"
  5181. +#define PFX DRV_NAME ": "
  5182. +
  5183. +struct gpio_buttons_dev {
  5184. + struct input_polled_dev *poll_dev;
  5185. + struct gpio_buttons_platform_data *pdata;
  5186. +};
  5187. +
  5188. +static void gpio_buttons_poll(struct input_polled_dev *dev)
  5189. +{
  5190. + struct gpio_buttons_dev *bdev = dev->private;
  5191. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  5192. + struct input_dev *input = dev->input;
  5193. + int i;
  5194. +
  5195. + for (i = 0; i < bdev->pdata->nbuttons; i++) {
  5196. + struct gpio_button *button = &pdata->buttons[i];
  5197. + unsigned int type = button->type ?: EV_KEY;
  5198. + int state;
  5199. +
  5200. + state = gpio_get_value(button->gpio) ? 1 : 0;
  5201. + state ^= button->active_low;
  5202. +
  5203. + if (state) {
  5204. + button->count++;
  5205. + } else {
  5206. + if (button->count >= button->threshold) {
  5207. + input_event(input, type, button->code, 1);
  5208. + input_sync(input);
  5209. + }
  5210. + button->count = 0;
  5211. + }
  5212. +
  5213. + if (button->count == button->threshold) {
  5214. + input_event(input, type, button->code, 0);
  5215. + input_sync(input);
  5216. + }
  5217. + }
  5218. +}
  5219. +
  5220. +static int __devinit gpio_buttons_probe(struct platform_device *pdev)
  5221. +{
  5222. + struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data;
  5223. + struct gpio_buttons_dev *bdev;
  5224. + struct input_polled_dev *poll_dev;
  5225. + struct input_dev *input;
  5226. + int error, i;
  5227. +
  5228. +
  5229. + if (!pdata)
  5230. + return -ENXIO;
  5231. +
  5232. + bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
  5233. + if (!bdev) {
  5234. + printk(KERN_ERR DRV_NAME "no memory for device\n");
  5235. + return -ENOMEM;
  5236. + }
  5237. +
  5238. + poll_dev = input_allocate_polled_device();
  5239. + if (!poll_dev) {
  5240. + printk(KERN_ERR DRV_NAME "no memory for polled device\n");
  5241. + error = -ENOMEM;
  5242. + goto err_free_bdev;
  5243. + }
  5244. +
  5245. + poll_dev->private = bdev;
  5246. + poll_dev->poll = gpio_buttons_poll;
  5247. + poll_dev->poll_interval = pdata->poll_interval;
  5248. +
  5249. + input = poll_dev->input;
  5250. +
  5251. + input->evbit[0] = BIT(EV_KEY);
  5252. + input->name = pdev->name;
  5253. + input->phys = "gpio-buttons/input0";
  5254. + input->dev.parent = &pdev->dev;
  5255. +
  5256. + input->id.bustype = BUS_HOST;
  5257. + input->id.vendor = 0x0001;
  5258. + input->id.product = 0x0001;
  5259. + input->id.version = 0x0100;
  5260. +
  5261. + for (i = 0; i < pdata->nbuttons; i++) {
  5262. + struct gpio_button *button = &pdata->buttons[i];
  5263. + unsigned int gpio = button->gpio;
  5264. + unsigned int type = button->type ?: EV_KEY;
  5265. +
  5266. + error = gpio_request(gpio, button->desc ?
  5267. + button->desc : DRV_NAME);
  5268. + if (error) {
  5269. + printk(KERN_ERR PFX "unable to claim gpio %u, "
  5270. + "error %d\n", gpio, error);
  5271. + goto err_free_gpio;
  5272. + }
  5273. +
  5274. + error = gpio_direction_input(gpio);
  5275. + if (error) {
  5276. + printk(KERN_ERR PFX "unable to set direction on "
  5277. + "gpio %u, error %d\n", gpio, error);
  5278. + goto err_free_gpio;
  5279. + }
  5280. +
  5281. + input_set_capability(input, type, button->code);
  5282. + button->count = 0;
  5283. + }
  5284. +
  5285. + bdev->poll_dev = poll_dev;
  5286. + bdev->pdata = pdata;
  5287. + platform_set_drvdata(pdev, bdev);
  5288. +
  5289. + error = input_register_polled_device(poll_dev);
  5290. + if (error) {
  5291. + printk(KERN_ERR PFX "unable to register polled device, "
  5292. + "error %d\n", error);
  5293. + goto err_free_gpio;
  5294. + }
  5295. +
  5296. + return 0;
  5297. +
  5298. +err_free_gpio:
  5299. + for (i = i - 1; i >= 0; i--)
  5300. + gpio_free(pdata->buttons[i].gpio);
  5301. +
  5302. + input_free_polled_device(poll_dev);
  5303. +
  5304. +err_free_bdev:
  5305. + kfree(bdev);
  5306. +
  5307. + platform_set_drvdata(pdev, NULL);
  5308. + return error;
  5309. +}
  5310. +
  5311. +static int __devexit gpio_buttons_remove(struct platform_device *pdev)
  5312. +{
  5313. + struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev);
  5314. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  5315. + int i;
  5316. +
  5317. + input_unregister_polled_device(bdev->poll_dev);
  5318. +
  5319. + for (i = 0; i < pdata->nbuttons; i++)
  5320. + gpio_free(pdata->buttons[i].gpio);
  5321. +
  5322. + input_free_polled_device(bdev->poll_dev);
  5323. +
  5324. + kfree(bdev);
  5325. + platform_set_drvdata(pdev, NULL);
  5326. +
  5327. + return 0;
  5328. +}
  5329. +
  5330. +static struct platform_driver gpio_buttons_driver = {
  5331. + .probe = gpio_buttons_probe,
  5332. + .remove = __devexit_p(gpio_buttons_remove),
  5333. + .driver = {
  5334. + .name = DRV_NAME,
  5335. + .owner = THIS_MODULE,
  5336. + },
  5337. +};
  5338. +
  5339. +static int __init gpio_buttons_init(void)
  5340. +{
  5341. + printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n");
  5342. + return platform_driver_register(&gpio_buttons_driver);
  5343. +}
  5344. +
  5345. +static void __exit gpio_buttons_exit(void)
  5346. +{
  5347. + platform_driver_unregister(&gpio_buttons_driver);
  5348. +}
  5349. +
  5350. +module_init(gpio_buttons_init);
  5351. +module_exit(gpio_buttons_exit);
  5352. +
  5353. +MODULE_LICENSE("GPL");
  5354. +MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
  5355. +MODULE_VERSION(DRV_VERSION);
  5356. +MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs");
  5357. +
  5358. diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/Kconfig linux-2.6.29.1/drivers/mtd/nand/Kconfig
  5359. --- linux-2.6.29.1.orig/drivers/mtd/nand/Kconfig 2009-04-02 22:55:27.000000000 +0200
  5360. +++ linux-2.6.29.1/drivers/mtd/nand/Kconfig 2009-04-13 14:27:34.731079923 +0200
  5361. @@ -427,4 +427,8 @@
  5362. Several Renesas SuperH CPU has FLCTL. This option enables support
  5363. for NAND Flash using FLCTL. This driver support SH7723.
  5364. +config MTD_NAND_RB4XX
  5365. + tristate "NAND flash driver for RouterBoard 4xx series"
  5366. + depends on MTD_NAND && ATHEROS_AR71XX
  5367. +
  5368. endif # MTD_NAND
  5369. diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/Makefile linux-2.6.29.1/drivers/mtd/nand/Makefile
  5370. --- linux-2.6.29.1.orig/drivers/mtd/nand/Makefile 2009-04-02 22:55:27.000000000 +0200
  5371. +++ linux-2.6.29.1/drivers/mtd/nand/Makefile 2009-04-13 14:27:34.731079923 +0200
  5372. @@ -29,6 +29,7 @@
  5373. obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
  5374. obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
  5375. obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
  5376. +obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
  5377. obj-$(CONFIG_MTD_ALAUDA) += alauda.o
  5378. obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
  5379. obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
  5380. diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.29.1/drivers/mtd/nand/rb4xx_nand.c
  5381. --- linux-2.6.29.1.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100
  5382. +++ linux-2.6.29.1/drivers/mtd/nand/rb4xx_nand.c 2009-04-13 14:27:34.735080153 +0200
  5383. @@ -0,0 +1,507 @@
  5384. +/*
  5385. + * NAND flash driver for the MikroTik RouterBoard 4xx series
  5386. + *
  5387. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  5388. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5389. + *
  5390. + * This file was based on the driver for Linux 2.6.22 published by
  5391. + * MikroTik for their RouterBoard 4xx series devices.
  5392. + *
  5393. + * This program is free software; you can redistribute it and/or modify it
  5394. + * under the terms of the GNU General Public License version 2 as published
  5395. + * by the Free Software Foundation.
  5396. + */
  5397. +
  5398. +#include <linux/init.h>
  5399. +#include <linux/mtd/nand.h>
  5400. +#include <linux/mtd/mtd.h>
  5401. +#include <linux/mtd/partitions.h>
  5402. +#include <linux/platform_device.h>
  5403. +#include <linux/delay.h>
  5404. +#include <linux/io.h>
  5405. +#include <linux/gpio.h>
  5406. +
  5407. +#include <asm/mach-ar71xx/ar71xx.h>
  5408. +
  5409. +#define DRV_NAME "rb4xx-nand"
  5410. +#define DRV_VERSION "0.1.10"
  5411. +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
  5412. +
  5413. +#define USE_FAST_READ 1
  5414. +#define USE_FAST_WRITE 1
  5415. +#undef RB4XX_NAND_DEBUG
  5416. +
  5417. +#ifdef RB4XX_NAND_DEBUG
  5418. +#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg)
  5419. +#else
  5420. +#define DBG(fmt, arg...) do {} while (0)
  5421. +#endif
  5422. +
  5423. +#define RB4XX_NAND_GPIO_RDY 5
  5424. +#define RB4XX_FLASH_HZ 33333334
  5425. +#define RB4XX_NAND_HZ 33333334
  5426. +
  5427. +#define SPI_CTRL_FASTEST 0x40
  5428. +#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */
  5429. +#define SBIT_IOC_BASE SPI_IOC_CS1
  5430. +#define SBIT_IOC_DO_SHIFT 0
  5431. +#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT)
  5432. +#define SBIT_IOC_DO2_SHIFT 18
  5433. +#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT)
  5434. +
  5435. +#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */
  5436. +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */
  5437. +#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */
  5438. +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */
  5439. +
  5440. +#define CFG_BIT_nCE 0x80
  5441. +#define CFG_BIT_CLE 0x40
  5442. +#define CFG_BIT_ALE 0x20
  5443. +#define CFG_BIT_FAN 0x10
  5444. +#define CFG_BIT_nLED4 0x08
  5445. +#define CFG_BIT_nLED3 0x04
  5446. +#define CFG_BIT_nLED2 0x02
  5447. +#define CFG_BIT_nLED1 0x01
  5448. +
  5449. +#define CFG_BIT_nLEDS \
  5450. + (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4)
  5451. +
  5452. +struct rb4xx_nand_info {
  5453. + struct nand_chip chip;
  5454. + struct mtd_info mtd;
  5455. +};
  5456. +
  5457. +/*
  5458. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  5459. + * will not be able to find the kernel that we load.
  5460. + */
  5461. +static struct nand_ecclayout rb4xx_nand_ecclayout = {
  5462. + .eccbytes = 6,
  5463. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  5464. + .oobavail = 9,
  5465. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  5466. +};
  5467. +
  5468. +static struct mtd_partition rb4xx_nand_partitions[] = {
  5469. + {
  5470. + .name = "booter",
  5471. + .offset = 0,
  5472. + .size = (256 * 1024),
  5473. + .mask_flags = MTD_WRITEABLE,
  5474. + },
  5475. + {
  5476. + .name = "kernel",
  5477. + .offset = (256 * 1024),
  5478. + .size = (4 * 1024 * 1024) - (256 * 1024),
  5479. + },
  5480. + {
  5481. + .name = "rootfs",
  5482. + .offset = MTDPART_OFS_NXTBLK,
  5483. + .size = MTDPART_SIZ_FULL,
  5484. + },
  5485. +};
  5486. +
  5487. +#if USE_FAST_READ
  5488. +#define SPI_NDATA_BASE 0x00800000
  5489. +static unsigned spi_ctrl_fread = SPI_CTRL_SAFE;
  5490. +static unsigned spi_ctrl_flash = SPI_CTRL_SAFE;
  5491. +extern unsigned mips_hpt_frequency;
  5492. +#endif
  5493. +
  5494. +static inline unsigned rb4xx_spi_rreg(unsigned r)
  5495. +{
  5496. + return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  5497. +}
  5498. +
  5499. +static inline void rb4xx_spi_wreg(unsigned r, unsigned v)
  5500. +{
  5501. + __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  5502. +}
  5503. +
  5504. +static inline void do_spi_clk(int bit)
  5505. +{
  5506. + unsigned bval = SBIT_IOC_BASE | (bit & 1);
  5507. +
  5508. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  5509. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  5510. +}
  5511. +
  5512. +static void do_spi_byte(uint8_t byte)
  5513. +{
  5514. + do_spi_clk(byte >> 7);
  5515. + do_spi_clk(byte >> 6);
  5516. + do_spi_clk(byte >> 5);
  5517. + do_spi_clk(byte >> 4);
  5518. + do_spi_clk(byte >> 3);
  5519. + do_spi_clk(byte >> 2);
  5520. + do_spi_clk(byte >> 1);
  5521. + do_spi_clk(byte);
  5522. +
  5523. + DBG("spi_byte sent 0x%02x got 0x%x\n",
  5524. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  5525. +}
  5526. +
  5527. +#if USE_FAST_WRITE
  5528. +static inline void do_spi_clk_fast(int bit1, int bit2)
  5529. +{
  5530. + unsigned bval = (SBIT_IOC_BASE |
  5531. + ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) |
  5532. + ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2));
  5533. +
  5534. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  5535. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  5536. +}
  5537. +
  5538. +static inline void do_spi_byte_fast(uint8_t byte)
  5539. +{
  5540. + do_spi_clk_fast(byte >> 7, byte >> 6);
  5541. + do_spi_clk_fast(byte >> 5, byte >> 4);
  5542. + do_spi_clk_fast(byte >> 3, byte >> 2);
  5543. + do_spi_clk_fast(byte >> 1, byte >> 0);
  5544. +
  5545. + DBG("spi_byte_fast sent 0x%02x got 0x%x\n",
  5546. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  5547. +}
  5548. +#else
  5549. +static inline void do_spi_byte_fast(uint8_t byte)
  5550. +{
  5551. + do_spi_byte(byte);
  5552. +}
  5553. +#endif /* USE_FAST_WRITE */
  5554. +
  5555. +static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData,
  5556. + unsigned recvCnt, uint8_t *recvData,
  5557. + const uint8_t *verifyData, int fastWrite)
  5558. +{
  5559. + unsigned i;
  5560. +
  5561. + DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt);
  5562. +
  5563. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  5564. + rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST);
  5565. +
  5566. + do_spi_byte(cmd);
  5567. +#if 0
  5568. + if (cmd == CPLD_CMD_READ_FAST) {
  5569. + do_spi_byte(0x80);
  5570. + do_spi_byte(0);
  5571. + do_spi_byte(0);
  5572. + }
  5573. +#endif
  5574. + for (i = 0; i < sendCnt; ++i) {
  5575. + if (fastWrite)
  5576. + do_spi_byte_fast(sendData[i]);
  5577. + else
  5578. + do_spi_byte(sendData[i]);
  5579. + }
  5580. +
  5581. + for (i = 0; i < recvCnt; ++i) {
  5582. + if (fastWrite)
  5583. + do_spi_byte_fast(0);
  5584. + else
  5585. + do_spi_byte(0);
  5586. +
  5587. + if (recvData) {
  5588. + recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff;
  5589. + } else if (verifyData) {
  5590. + if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS)
  5591. + & 0xff))
  5592. + break;
  5593. + }
  5594. + }
  5595. +
  5596. + rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0);
  5597. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash);
  5598. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  5599. +
  5600. + return i == recvCnt;
  5601. +}
  5602. +
  5603. +static int got_write = 1;
  5604. +
  5605. +static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt)
  5606. +{
  5607. + do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1);
  5608. + got_write = 1;
  5609. +}
  5610. +
  5611. +static void rb4xx_nand_write_byte(uint8_t byte)
  5612. +{
  5613. + rb4xx_nand_write_data(&byte, 1);
  5614. +}
  5615. +
  5616. +#if USE_FAST_READ
  5617. +static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt)
  5618. +{
  5619. + static unsigned nboffset = 0x100000;
  5620. + unsigned addr;
  5621. +
  5622. + if (got_write) {
  5623. + nboffset = (nboffset + 31) & ~31;
  5624. + if (nboffset >= 0x100000) /* 1MB */
  5625. + nboffset = 0;
  5626. +
  5627. + got_write = 0;
  5628. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  5629. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread);
  5630. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  5631. + }
  5632. +
  5633. + addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset;
  5634. + DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt);
  5635. +
  5636. + nboffset += cnt;
  5637. + return (uint8_t *)addr;
  5638. +}
  5639. +
  5640. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  5641. +{
  5642. + unsigned size32 = cnt & ~31;
  5643. + unsigned remain = cnt & 31;
  5644. +
  5645. + if (size32) {
  5646. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  5647. + memcpy(buf, (void *)addr, size32);
  5648. + }
  5649. +
  5650. + if (remain) {
  5651. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  5652. + buf + size32, NULL, 0);
  5653. + }
  5654. +}
  5655. +
  5656. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  5657. +{
  5658. + unsigned size32 = cnt & ~31;
  5659. + unsigned remain = cnt & 31;
  5660. +
  5661. + if (size32) {
  5662. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  5663. + if (memcmp(buf, (void *)addr, size32) != 0)
  5664. + return 0;
  5665. + }
  5666. +
  5667. + if (remain) {
  5668. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  5669. + NULL, buf + size32, 0);
  5670. + }
  5671. + return 1;
  5672. +}
  5673. +#else /* USE_FAST_READ */
  5674. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  5675. +{
  5676. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0);
  5677. +}
  5678. +
  5679. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  5680. +{
  5681. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0);
  5682. +}
  5683. +#endif /* USE_FAST_READ */
  5684. +
  5685. +static void rb4xx_nand_write_cfg(uint8_t byte)
  5686. +{
  5687. + do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0);
  5688. + got_write = 1;
  5689. +}
  5690. +
  5691. +static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
  5692. +{
  5693. + return gpio_get_value(RB4XX_NAND_GPIO_RDY);
  5694. +}
  5695. +
  5696. +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  5697. + unsigned int ctrl)
  5698. +{
  5699. + if (ctrl & NAND_CTRL_CHANGE) {
  5700. + uint8_t cfg = CFG_BIT_nLEDS;
  5701. +
  5702. + cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0;
  5703. + cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0;
  5704. + cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE;
  5705. +
  5706. + rb4xx_nand_write_cfg(cfg);
  5707. + }
  5708. +
  5709. + if (cmd != NAND_CMD_NONE)
  5710. + rb4xx_nand_write_byte(cmd);
  5711. +}
  5712. +
  5713. +static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd)
  5714. +{
  5715. + uint8_t byte = 0;
  5716. +
  5717. + rb4xx_nand_read_data(&byte, 1);
  5718. + return byte;
  5719. +}
  5720. +
  5721. +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
  5722. + int len)
  5723. +{
  5724. + rb4xx_nand_write_data(buf, len);
  5725. +}
  5726. +
  5727. +static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf,
  5728. + int len)
  5729. +{
  5730. + rb4xx_nand_read_data(buf, len);
  5731. +}
  5732. +
  5733. +static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
  5734. + int len)
  5735. +{
  5736. + if (!rb4xx_nand_verify_data(buf, len))
  5737. + return -EFAULT;
  5738. +
  5739. + return 0;
  5740. +}
  5741. +
  5742. +static unsigned get_spi_ctrl(unsigned hz_max, const char *name)
  5743. +{
  5744. + unsigned div;
  5745. +
  5746. + div = (ar71xx_ahb_freq - 1) / (2 * hz_max);
  5747. + /*
  5748. + * CPU has a bug at (div == 0) - first bit read is random
  5749. + */
  5750. + if (div == 0)
  5751. + ++div;
  5752. +
  5753. + if (name) {
  5754. + unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000;
  5755. + unsigned div_real = 2 * (div + 1);
  5756. + printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n",
  5757. + name,
  5758. + ahb_khz / div_real,
  5759. + ahb_khz, div_real);
  5760. + }
  5761. +
  5762. + return SPI_CTRL_FASTEST + div;
  5763. +}
  5764. +
  5765. +static int __init rb4xx_nand_probe(struct platform_device *pdev)
  5766. +{
  5767. + struct rb4xx_nand_info *info;
  5768. + int ret;
  5769. +
  5770. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  5771. +
  5772. + ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY");
  5773. + if (ret) {
  5774. + printk(KERN_ERR "rb4xx-nand: gpio request failed\n");
  5775. + return ret;
  5776. + }
  5777. +
  5778. + ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY);
  5779. + if (ret) {
  5780. + printk(KERN_ERR "rb4xx-nand: unable to set input mode "
  5781. + "on gpio%d\n", RB4XX_NAND_GPIO_RDY);
  5782. + goto err_free_gpio;
  5783. + }
  5784. +
  5785. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  5786. + if (!info) {
  5787. + printk(KERN_ERR "rb4xx-nand: no memory for private data\n");
  5788. + ret = -ENOMEM;
  5789. + goto err_free_gpio;
  5790. + }
  5791. +
  5792. +#if USE_FAST_READ
  5793. + spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND");
  5794. +#endif
  5795. + spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH");
  5796. +
  5797. + rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE);
  5798. +
  5799. + info->chip.priv = &info;
  5800. + info->mtd.priv = &info->chip;
  5801. + info->mtd.owner = THIS_MODULE;
  5802. +
  5803. + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
  5804. + info->chip.dev_ready = rb4xx_nand_dev_ready;
  5805. + info->chip.read_byte = rb4xx_nand_read_byte;
  5806. + info->chip.write_buf = rb4xx_nand_write_buf;
  5807. + info->chip.read_buf = rb4xx_nand_read_buf;
  5808. + info->chip.verify_buf = rb4xx_nand_verify_buf;
  5809. +
  5810. + info->chip.chip_delay = 25;
  5811. + info->chip.ecc.mode = NAND_ECC_SOFT;
  5812. + info->chip.options |= NAND_NO_AUTOINCR;
  5813. +
  5814. + platform_set_drvdata(pdev, info);
  5815. +
  5816. + ret = nand_scan_ident(&info->mtd, 1);
  5817. + if (ret) {
  5818. + ret = -ENXIO;
  5819. + goto err_free_info;
  5820. + }
  5821. +
  5822. + if (info->mtd.writesize == 512)
  5823. + info->chip.ecc.layout = &rb4xx_nand_ecclayout;
  5824. +
  5825. + ret = nand_scan_tail(&info->mtd);
  5826. + if (ret) {
  5827. + return -ENXIO;
  5828. + goto err_set_drvdata;
  5829. + }
  5830. +
  5831. +#ifdef CONFIG_MTD_PARTITIONS
  5832. + ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions,
  5833. + ARRAY_SIZE(rb4xx_nand_partitions));
  5834. +#else
  5835. + ret = add_mtd_device(&info->mtd);
  5836. +#endif
  5837. + if (ret)
  5838. + goto err_release_nand;
  5839. +
  5840. + return 0;
  5841. +
  5842. +err_release_nand:
  5843. + nand_release(&info->mtd);
  5844. +err_set_drvdata:
  5845. + platform_set_drvdata(pdev, NULL);
  5846. +err_free_info:
  5847. + kfree(info);
  5848. +err_free_gpio:
  5849. + gpio_free(RB4XX_NAND_GPIO_RDY);
  5850. + return ret;
  5851. +}
  5852. +
  5853. +static int __devexit rb4xx_nand_remove(struct platform_device *pdev)
  5854. +{
  5855. + struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
  5856. +
  5857. + nand_release(&info->mtd);
  5858. + platform_set_drvdata(pdev, NULL);
  5859. + kfree(info);
  5860. +
  5861. + return 0;
  5862. +}
  5863. +
  5864. +static struct platform_driver rb4xx_nand_driver = {
  5865. + .probe = rb4xx_nand_probe,
  5866. + .remove = __devexit_p(rb4xx_nand_remove),
  5867. + .driver = {
  5868. + .name = DRV_NAME,
  5869. + .owner = THIS_MODULE,
  5870. + },
  5871. +};
  5872. +
  5873. +static int __init rb4xx_nand_init(void)
  5874. +{
  5875. + return platform_driver_register(&rb4xx_nand_driver);
  5876. +}
  5877. +
  5878. +static void __exit rb4xx_nand_exit(void)
  5879. +{
  5880. + platform_driver_unregister(&rb4xx_nand_driver);
  5881. +}
  5882. +
  5883. +module_init(rb4xx_nand_init);
  5884. +module_exit(rb4xx_nand_exit);
  5885. +
  5886. +MODULE_DESCRIPTION(DRV_DESC);
  5887. +MODULE_VERSION(DRV_VERSION);
  5888. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  5889. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  5890. +MODULE_LICENSE("GPL v2");
  5891. diff -Nur linux-2.6.29.1.orig/drivers/net/Kconfig linux-2.6.29.1/drivers/net/Kconfig
  5892. --- linux-2.6.29.1.orig/drivers/net/Kconfig 2009-04-02 22:55:27.000000000 +0200
  5893. +++ linux-2.6.29.1/drivers/net/Kconfig 2009-04-13 14:27:34.763080366 +0200
  5894. @@ -1945,6 +1945,8 @@
  5895. The safe and default value for this is N.
  5896. +source drivers/net/ag71xx/Kconfig
  5897. +
  5898. config DL2K
  5899. tristate "DL2000/TC902x-based Gigabit Ethernet support"
  5900. depends on PCI
  5901. diff -Nur linux-2.6.29.1.orig/drivers/net/Makefile linux-2.6.29.1/drivers/net/Makefile
  5902. --- linux-2.6.29.1.orig/drivers/net/Makefile 2009-04-02 22:55:27.000000000 +0200
  5903. +++ linux-2.6.29.1/drivers/net/Makefile 2009-04-13 14:27:34.767081713 +0200
  5904. @@ -2,6 +2,7 @@
  5905. # Makefile for the Linux network (ethercard) device drivers.
  5906. #
  5907. +obj-$(CONFIG_AG71XX) += ag71xx/
  5908. obj-$(CONFIG_E1000) += e1000/
  5909. obj-$(CONFIG_E1000E) += e1000e/
  5910. obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
  5911. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/Kconfig linux-2.6.29.1/drivers/net/ag71xx/Kconfig
  5912. --- linux-2.6.29.1.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  5913. +++ linux-2.6.29.1/drivers/net/ag71xx/Kconfig 2009-04-13 14:27:34.767081713 +0200
  5914. @@ -0,0 +1,23 @@
  5915. +config AG71XX
  5916. + tristate "Atheros AR71xx built-in ethernet mac support"
  5917. + depends on ATHEROS_AR71XX
  5918. + select PHYLIB
  5919. + help
  5920. + If you wish to compile a kernel for AR71xx/91xx and enable
  5921. + ethernet support, then you should always answer Y to this.
  5922. +
  5923. +config AG71XX_DEBUG
  5924. + bool "Atheros AR71xx built-in ethernet driver debugging"
  5925. + depends on AG71XX
  5926. + default n
  5927. + help
  5928. + Atheros AR71xx built-in ethernet driver debugging messages.
  5929. +
  5930. +config AG71XX_AR8216_SUPPORT
  5931. + bool "special support for the Atheros AR8216 switch"
  5932. + depends on AG71XX
  5933. + default n
  5934. + default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU
  5935. + help
  5936. + Say 'y' here if you want to enable special support for the
  5937. + Atheros AR8216 switch found on some boards.
  5938. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/Makefile linux-2.6.29.1/drivers/net/ag71xx/Makefile
  5939. --- linux-2.6.29.1.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  5940. +++ linux-2.6.29.1/drivers/net/ag71xx/Makefile 2009-04-13 14:27:34.771082502 +0200
  5941. @@ -0,0 +1,13 @@
  5942. +#
  5943. +# Makefile for the Atheros AR71xx built-in ethernet macs
  5944. +#
  5945. +
  5946. +ag71xx-y += ag71xx_main.o
  5947. +ag71xx-y += ag71xx_ethtool.o
  5948. +ag71xx-y += ag71xx_phy.o
  5949. +ag71xx-y += ag71xx_mdio.o
  5950. +
  5951. +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o
  5952. +
  5953. +obj-$(CONFIG_AG71XX) += ag71xx.o
  5954. +
  5955. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.29.1/drivers/net/ag71xx/ag71xx.h
  5956. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100
  5957. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx.h 2009-04-13 14:27:34.799084111 +0200
  5958. @@ -0,0 +1,449 @@
  5959. +/*
  5960. + * Atheros AR71xx built-in ethernet mac driver
  5961. + *
  5962. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  5963. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5964. + *
  5965. + * Based on Atheros' AG7100 driver
  5966. + *
  5967. + * This program is free software; you can redistribute it and/or modify it
  5968. + * under the terms of the GNU General Public License version 2 as published
  5969. + * by the Free Software Foundation.
  5970. + */
  5971. +
  5972. +#ifndef __AG71XX_H
  5973. +#define __AG71XX_H
  5974. +
  5975. +#include <linux/kernel.h>
  5976. +#include <linux/version.h>
  5977. +#include <linux/module.h>
  5978. +#include <linux/init.h>
  5979. +#include <linux/types.h>
  5980. +#include <linux/random.h>
  5981. +#include <linux/spinlock.h>
  5982. +#include <linux/interrupt.h>
  5983. +#include <linux/platform_device.h>
  5984. +#include <linux/ethtool.h>
  5985. +#include <linux/etherdevice.h>
  5986. +#include <linux/phy.h>
  5987. +#include <linux/skbuff.h>
  5988. +#include <linux/dma-mapping.h>
  5989. +#include <linux/workqueue.h>
  5990. +
  5991. +#include <linux/bitops.h>
  5992. +
  5993. +#include <asm/mach-ar71xx/ar71xx.h>
  5994. +#include <asm/mach-ar71xx/platform.h>
  5995. +
  5996. +#define ETH_FCS_LEN 4
  5997. +
  5998. +#define AG71XX_DRV_NAME "ag71xx"
  5999. +#define AG71XX_DRV_VERSION "0.5.21"
  6000. +
  6001. +#define AG71XX_NAPI_WEIGHT 64
  6002. +#define AG71XX_OOM_REFILL (1 + HZ/10)
  6003. +
  6004. +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
  6005. +#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
  6006. +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
  6007. +
  6008. +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
  6009. +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
  6010. +
  6011. +#define AG71XX_TX_FIFO_LEN 2048
  6012. +#define AG71XX_TX_MTU_LEN 1536
  6013. +#define AG71XX_RX_PKT_RESERVE 64
  6014. +#define AG71XX_RX_PKT_SIZE \
  6015. + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
  6016. +
  6017. +#define AG71XX_TX_RING_SIZE 64
  6018. +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
  6019. +#define AG71XX_TX_THRES_WAKEUP \
  6020. + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
  6021. +
  6022. +#define AG71XX_RX_RING_SIZE 128
  6023. +
  6024. +#ifdef CONFIG_AG71XX_DEBUG
  6025. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  6026. +#else
  6027. +#define DBG(fmt, args...) do {} while (0)
  6028. +#endif
  6029. +
  6030. +#define ag71xx_assert(_cond) \
  6031. +do { \
  6032. + if (_cond) \
  6033. + break; \
  6034. + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \
  6035. + BUG(); \
  6036. +} while (0)
  6037. +
  6038. +struct ag71xx_desc {
  6039. + u32 data;
  6040. + u32 ctrl;
  6041. +#define DESC_EMPTY BIT(31)
  6042. +#define DESC_MORE BIT(24)
  6043. +#define DESC_PKTLEN_M 0x1fff
  6044. + u32 next;
  6045. + u32 pad;
  6046. +};
  6047. +
  6048. +struct ag71xx_buf {
  6049. + struct sk_buff *skb;
  6050. +};
  6051. +
  6052. +struct ag71xx_ring {
  6053. + struct ag71xx_buf *buf;
  6054. + struct ag71xx_desc *descs;
  6055. + dma_addr_t descs_dma;
  6056. + unsigned int curr;
  6057. + unsigned int dirty;
  6058. + unsigned int size;
  6059. +};
  6060. +
  6061. +struct ag71xx_mdio {
  6062. + struct mii_bus *mii_bus;
  6063. + int mii_irq[PHY_MAX_ADDR];
  6064. + void __iomem *mdio_base;
  6065. +};
  6066. +
  6067. +struct ag71xx {
  6068. + void __iomem *mac_base;
  6069. + void __iomem *mac_base2;
  6070. + void __iomem *mii_ctrl;
  6071. +
  6072. + spinlock_t lock;
  6073. + struct platform_device *pdev;
  6074. + struct net_device *dev;
  6075. + struct napi_struct napi;
  6076. + u32 msg_enable;
  6077. +
  6078. + struct ag71xx_ring rx_ring;
  6079. + struct ag71xx_ring tx_ring;
  6080. +
  6081. + struct mii_bus *mii_bus;
  6082. + struct phy_device *phy_dev;
  6083. +
  6084. + unsigned int link;
  6085. + unsigned int speed;
  6086. + int duplex;
  6087. +
  6088. + struct work_struct restart_work;
  6089. + struct timer_list oom_timer;
  6090. +};
  6091. +
  6092. +extern struct ethtool_ops ag71xx_ethtool_ops;
  6093. +
  6094. +extern struct ag71xx_mdio *ag71xx_mdio_bus;
  6095. +extern int ag71xx_mdio_driver_init(void) __init;
  6096. +extern void ag71xx_mdio_driver_exit(void);
  6097. +
  6098. +extern int ag71xx_phy_connect(struct ag71xx *ag);
  6099. +extern void ag71xx_phy_disconnect(struct ag71xx *ag);
  6100. +extern void ag71xx_phy_start(struct ag71xx *ag);
  6101. +extern void ag71xx_phy_stop(struct ag71xx *ag);
  6102. +
  6103. +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
  6104. +{
  6105. + return ag->pdev->dev.platform_data;
  6106. +}
  6107. +
  6108. +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
  6109. +{
  6110. + return ((desc->ctrl & DESC_EMPTY) != 0);
  6111. +}
  6112. +
  6113. +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
  6114. +{
  6115. + return (desc->ctrl & DESC_PKTLEN_M);
  6116. +}
  6117. +
  6118. +/* Register offsets */
  6119. +#define AG71XX_REG_MAC_CFG1 0x0000
  6120. +#define AG71XX_REG_MAC_CFG2 0x0004
  6121. +#define AG71XX_REG_MAC_IPG 0x0008
  6122. +#define AG71XX_REG_MAC_HDX 0x000c
  6123. +#define AG71XX_REG_MAC_MFL 0x0010
  6124. +#define AG71XX_REG_MII_CFG 0x0020
  6125. +#define AG71XX_REG_MII_CMD 0x0024
  6126. +#define AG71XX_REG_MII_ADDR 0x0028
  6127. +#define AG71XX_REG_MII_CTRL 0x002c
  6128. +#define AG71XX_REG_MII_STATUS 0x0030
  6129. +#define AG71XX_REG_MII_IND 0x0034
  6130. +#define AG71XX_REG_MAC_IFCTL 0x0038
  6131. +#define AG71XX_REG_MAC_ADDR1 0x0040
  6132. +#define AG71XX_REG_MAC_ADDR2 0x0044
  6133. +#define AG71XX_REG_FIFO_CFG0 0x0048
  6134. +#define AG71XX_REG_FIFO_CFG1 0x004c
  6135. +#define AG71XX_REG_FIFO_CFG2 0x0050
  6136. +#define AG71XX_REG_FIFO_CFG3 0x0054
  6137. +#define AG71XX_REG_FIFO_CFG4 0x0058
  6138. +#define AG71XX_REG_FIFO_CFG5 0x005c
  6139. +#define AG71XX_REG_FIFO_RAM0 0x0060
  6140. +#define AG71XX_REG_FIFO_RAM1 0x0064
  6141. +#define AG71XX_REG_FIFO_RAM2 0x0068
  6142. +#define AG71XX_REG_FIFO_RAM3 0x006c
  6143. +#define AG71XX_REG_FIFO_RAM4 0x0070
  6144. +#define AG71XX_REG_FIFO_RAM5 0x0074
  6145. +#define AG71XX_REG_FIFO_RAM6 0x0078
  6146. +#define AG71XX_REG_FIFO_RAM7 0x007c
  6147. +
  6148. +#define AG71XX_REG_TX_CTRL 0x0180
  6149. +#define AG71XX_REG_TX_DESC 0x0184
  6150. +#define AG71XX_REG_TX_STATUS 0x0188
  6151. +#define AG71XX_REG_RX_CTRL 0x018c
  6152. +#define AG71XX_REG_RX_DESC 0x0190
  6153. +#define AG71XX_REG_RX_STATUS 0x0194
  6154. +#define AG71XX_REG_INT_ENABLE 0x0198
  6155. +#define AG71XX_REG_INT_STATUS 0x019c
  6156. +
  6157. +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
  6158. +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
  6159. +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
  6160. +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
  6161. +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
  6162. +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
  6163. +#define MAC_CFG1_LB BIT(8) /* Loopback mode */
  6164. +#define MAC_CFG1_SR BIT(31) /* Soft Reset */
  6165. +
  6166. +#define MAC_CFG2_FDX BIT(0)
  6167. +#define MAC_CFG2_CRC_EN BIT(1)
  6168. +#define MAC_CFG2_PAD_CRC_EN BIT(2)
  6169. +#define MAC_CFG2_LEN_CHECK BIT(4)
  6170. +#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
  6171. +#define MAC_CFG2_IF_1000 BIT(9)
  6172. +#define MAC_CFG2_IF_10_100 BIT(8)
  6173. +
  6174. +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
  6175. +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
  6176. +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
  6177. +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
  6178. +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
  6179. +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
  6180. + | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
  6181. +
  6182. +#define FIFO_CFG0_ENABLE_SHIFT 8
  6183. +
  6184. +#define FIFO_CFG4_DE BIT(0) /* Drop Event */
  6185. +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
  6186. +#define FIFO_CFG4_FC BIT(2) /* False Carrier */
  6187. +#define FIFO_CFG4_CE BIT(3) /* Code Error */
  6188. +#define FIFO_CFG4_CR BIT(4) /* CRC error */
  6189. +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
  6190. +#define FIFO_CFG4_LO BIT(6) /* Length out of range */
  6191. +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
  6192. +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
  6193. +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
  6194. +#define FIFO_CFG4_DR BIT(10) /* Dribble */
  6195. +#define FIFO_CFG4_LE BIT(11) /* Long Event */
  6196. +#define FIFO_CFG4_CF BIT(12) /* Control Frame */
  6197. +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
  6198. +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
  6199. +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
  6200. +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
  6201. +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
  6202. +
  6203. +#define FIFO_CFG5_DE BIT(0) /* Drop Event */
  6204. +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
  6205. +#define FIFO_CFG5_FC BIT(2) /* False Carrier */
  6206. +#define FIFO_CFG5_CE BIT(3) /* Code Error */
  6207. +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
  6208. +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
  6209. +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
  6210. +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
  6211. +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
  6212. +#define FIFO_CFG5_DR BIT(9) /* Dribble */
  6213. +#define FIFO_CFG5_CF BIT(10) /* Control Frame */
  6214. +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
  6215. +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
  6216. +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
  6217. +#define FIFO_CFG5_LE BIT(14) /* Long Event */
  6218. +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
  6219. +#define FIFO_CFG5_16 BIT(16) /* unknown */
  6220. +#define FIFO_CFG5_17 BIT(17) /* unknown */
  6221. +#define FIFO_CFG5_SF BIT(18) /* Short Frame */
  6222. +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
  6223. +
  6224. +#define AG71XX_INT_TX_PS BIT(0)
  6225. +#define AG71XX_INT_TX_UR BIT(1)
  6226. +#define AG71XX_INT_TX_BE BIT(3)
  6227. +#define AG71XX_INT_RX_PR BIT(4)
  6228. +#define AG71XX_INT_RX_OF BIT(6)
  6229. +#define AG71XX_INT_RX_BE BIT(7)
  6230. +
  6231. +#define MAC_IFCTL_SPEED BIT(16)
  6232. +
  6233. +#define MII_CFG_CLK_DIV_4 0
  6234. +#define MII_CFG_CLK_DIV_6 2
  6235. +#define MII_CFG_CLK_DIV_8 3
  6236. +#define MII_CFG_CLK_DIV_10 4
  6237. +#define MII_CFG_CLK_DIV_14 5
  6238. +#define MII_CFG_CLK_DIV_20 6
  6239. +#define MII_CFG_CLK_DIV_28 7
  6240. +#define MII_CFG_RESET BIT(31)
  6241. +
  6242. +#define MII_CMD_WRITE 0x0
  6243. +#define MII_CMD_READ 0x1
  6244. +#define MII_ADDR_SHIFT 8
  6245. +#define MII_IND_BUSY BIT(0)
  6246. +#define MII_IND_INVALID BIT(2)
  6247. +
  6248. +#define TX_CTRL_TXE BIT(0) /* Tx Enable */
  6249. +
  6250. +#define TX_STATUS_PS BIT(0) /* Packet Sent */
  6251. +#define TX_STATUS_UR BIT(1) /* Tx Underrun */
  6252. +#define TX_STATUS_BE BIT(3) /* Bus Error */
  6253. +
  6254. +#define RX_CTRL_RXE BIT(0) /* Rx Enable */
  6255. +
  6256. +#define RX_STATUS_PR BIT(0) /* Packet Received */
  6257. +#define RX_STATUS_OF BIT(2) /* Rx Overflow */
  6258. +#define RX_STATUS_BE BIT(3) /* Bus Error */
  6259. +
  6260. +#define MII_CTRL_IF_MASK 3
  6261. +#define MII_CTRL_SPEED_SHIFT 4
  6262. +#define MII_CTRL_SPEED_MASK 3
  6263. +#define MII_CTRL_SPEED_10 0
  6264. +#define MII_CTRL_SPEED_100 1
  6265. +#define MII_CTRL_SPEED_1000 2
  6266. +
  6267. +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
  6268. +{
  6269. + void __iomem *r;
  6270. +
  6271. + switch (reg) {
  6272. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  6273. + r = ag->mac_base + reg;
  6274. + __raw_writel(value, r);
  6275. + __raw_readl(r);
  6276. + break;
  6277. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  6278. + r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL;
  6279. + __raw_writel(value, r);
  6280. + __raw_readl(r);
  6281. + break;
  6282. + default:
  6283. + BUG();
  6284. + }
  6285. +}
  6286. +
  6287. +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
  6288. +{
  6289. + void __iomem *r;
  6290. + u32 ret;
  6291. +
  6292. + switch (reg) {
  6293. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  6294. + r = ag->mac_base + reg;
  6295. + ret = __raw_readl(r);
  6296. + break;
  6297. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  6298. + r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL;
  6299. + ret = __raw_readl(r);
  6300. + break;
  6301. + default:
  6302. + BUG();
  6303. + }
  6304. +
  6305. + return ret;
  6306. +}
  6307. +
  6308. +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
  6309. +{
  6310. + void __iomem *r;
  6311. +
  6312. + switch (reg) {
  6313. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  6314. + r = ag->mac_base + reg;
  6315. + __raw_writel(__raw_readl(r) | mask, r);
  6316. + __raw_readl(r);
  6317. + break;
  6318. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  6319. + r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL;
  6320. + __raw_writel(__raw_readl(r) | mask, r);
  6321. + __raw_readl(r);
  6322. + break;
  6323. + default:
  6324. + BUG();
  6325. + }
  6326. +}
  6327. +
  6328. +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
  6329. +{
  6330. + void __iomem *r;
  6331. +
  6332. + switch (reg) {
  6333. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  6334. + r = ag->mac_base + reg;
  6335. + __raw_writel(__raw_readl(r) & ~mask, r);
  6336. + __raw_readl(r);
  6337. + break;
  6338. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  6339. + r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL;
  6340. + __raw_writel(__raw_readl(r) & ~mask, r);
  6341. + __raw_readl(r);
  6342. + break;
  6343. + default:
  6344. + BUG();
  6345. + }
  6346. +}
  6347. +
  6348. +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
  6349. +{
  6350. + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
  6351. +}
  6352. +
  6353. +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
  6354. +{
  6355. + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
  6356. +}
  6357. +
  6358. +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
  6359. +{
  6360. + __raw_writel(value, ag->mii_ctrl);
  6361. + __raw_readl(ag->mii_ctrl);
  6362. +}
  6363. +
  6364. +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
  6365. +{
  6366. + return __raw_readl(ag->mii_ctrl);
  6367. +}
  6368. +
  6369. +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
  6370. + unsigned int mii_if)
  6371. +{
  6372. + u32 t;
  6373. +
  6374. + t = ag71xx_mii_ctrl_rr(ag);
  6375. + t &= ~(MII_CTRL_IF_MASK);
  6376. + t |= (mii_if & MII_CTRL_IF_MASK);
  6377. + ag71xx_mii_ctrl_wr(ag, t);
  6378. +}
  6379. +
  6380. +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
  6381. + unsigned int speed)
  6382. +{
  6383. + u32 t;
  6384. +
  6385. + t = ag71xx_mii_ctrl_rr(ag);
  6386. + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
  6387. + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
  6388. + ag71xx_mii_ctrl_wr(ag, t);
  6389. +}
  6390. +
  6391. +#ifdef CONFIG_AG71XX_AR8216_SUPPORT
  6392. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  6393. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  6394. +#else
  6395. +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
  6396. + struct sk_buff *skb)
  6397. +{
  6398. +}
  6399. +
  6400. +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  6401. + struct sk_buff *skb)
  6402. +{
  6403. + return 0;
  6404. +}
  6405. +#endif
  6406. +
  6407. +#endif /* _AG71XX_H */
  6408. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ar8216.c
  6409. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100
  6410. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ar8216.c 2009-04-13 14:27:34.803084620 +0200
  6411. @@ -0,0 +1,53 @@
  6412. +/*
  6413. + * Atheros AR71xx built-in ethernet mac driver
  6414. + * Special support for the Atheros ar8216 switch chip
  6415. + *
  6416. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  6417. + *
  6418. + * Based on Atheros' AG7100 driver
  6419. + *
  6420. + * This program is free software; you can redistribute it and/or modify it
  6421. + * under the terms of the GNU General Public License version 2 as published
  6422. + * by the Free Software Foundation.
  6423. + */
  6424. +
  6425. +#include "ag71xx.h"
  6426. +
  6427. +#define AR8216_PACKET_TYPE_MASK 0xf
  6428. +#define AR8216_PACKET_TYPE_NORMAL 0
  6429. +
  6430. +#define AR8216_HEADER_LEN 2
  6431. +
  6432. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
  6433. +{
  6434. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  6435. +
  6436. + if (!pdata->has_ar8216)
  6437. + return;
  6438. +
  6439. + skb_push(skb, AR8216_HEADER_LEN);
  6440. + skb->data[0] = 0x10;
  6441. + skb->data[1] = 0x80;
  6442. +}
  6443. +
  6444. +int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  6445. + struct sk_buff *skb)
  6446. +{
  6447. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  6448. + u8 type;
  6449. +
  6450. + if (!pdata->has_ar8216)
  6451. + return 0;
  6452. +
  6453. + type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
  6454. +
  6455. + switch (type) {
  6456. + case AR8216_PACKET_TYPE_NORMAL:
  6457. + skb_pull(skb, AR8216_HEADER_LEN);
  6458. + break;
  6459. + default:
  6460. + return -EINVAL;
  6461. + }
  6462. +
  6463. + return 0;
  6464. +}
  6465. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ethtool.c
  6466. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
  6467. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ethtool.c 2009-04-13 14:27:34.803084620 +0200
  6468. @@ -0,0 +1,71 @@
  6469. +/*
  6470. + * Atheros AR71xx built-in ethernet mac driver
  6471. + *
  6472. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6473. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6474. + *
  6475. + * Based on Atheros' AG7100 driver
  6476. + *
  6477. + * This program is free software; you can redistribute it and/or modify it
  6478. + * under the terms of the GNU General Public License version 2 as published
  6479. + * by the Free Software Foundation.
  6480. + */
  6481. +
  6482. +#include "ag71xx.h"
  6483. +
  6484. +static int ag71xx_ethtool_get_settings(struct net_device *dev,
  6485. + struct ethtool_cmd *cmd)
  6486. +{
  6487. + struct ag71xx *ag = netdev_priv(dev);
  6488. + struct phy_device *phydev = ag->phy_dev;
  6489. +
  6490. + if (!phydev)
  6491. + return -ENODEV;
  6492. +
  6493. + return phy_ethtool_gset(phydev, cmd);
  6494. +}
  6495. +
  6496. +static int ag71xx_ethtool_set_settings(struct net_device *dev,
  6497. + struct ethtool_cmd *cmd)
  6498. +{
  6499. + struct ag71xx *ag = netdev_priv(dev);
  6500. + struct phy_device *phydev = ag->phy_dev;
  6501. +
  6502. + if (!phydev)
  6503. + return -ENODEV;
  6504. +
  6505. + return phy_ethtool_sset(phydev, cmd);
  6506. +}
  6507. +
  6508. +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev,
  6509. + struct ethtool_drvinfo *info)
  6510. +{
  6511. + struct ag71xx *ag = netdev_priv(dev);
  6512. +
  6513. + strcpy(info->driver, ag->pdev->dev.driver->name);
  6514. + strcpy(info->version, AG71XX_DRV_VERSION);
  6515. + strcpy(info->bus_info, ag->pdev->dev.bus_id);
  6516. +}
  6517. +
  6518. +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev)
  6519. +{
  6520. + struct ag71xx *ag = netdev_priv(dev);
  6521. +
  6522. + return ag->msg_enable;
  6523. +}
  6524. +
  6525. +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level)
  6526. +{
  6527. + struct ag71xx *ag = netdev_priv(dev);
  6528. +
  6529. + ag->msg_enable = msg_level;
  6530. +}
  6531. +
  6532. +struct ethtool_ops ag71xx_ethtool_ops = {
  6533. + .set_settings = ag71xx_ethtool_set_settings,
  6534. + .get_settings = ag71xx_ethtool_get_settings,
  6535. + .get_drvinfo = ag71xx_ethtool_get_drvinfo,
  6536. + .get_msglevel = ag71xx_ethtool_get_msglevel,
  6537. + .set_msglevel = ag71xx_ethtool_set_msglevel,
  6538. + .get_link = ethtool_op_get_link,
  6539. +};
  6540. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_main.c
  6541. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100
  6542. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_main.c 2009-04-13 18:00:36.641934324 +0200
  6543. @@ -0,0 +1,990 @@
  6544. +/*
  6545. + * Atheros AR71xx built-in ethernet mac driver
  6546. + *
  6547. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6548. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6549. + *
  6550. + * Based on Atheros' AG7100 driver
  6551. + *
  6552. + * This program is free software; you can redistribute it and/or modify it
  6553. + * under the terms of the GNU General Public License version 2 as published
  6554. + * by the Free Software Foundation.
  6555. + */
  6556. +
  6557. +#include "ag71xx.h"
  6558. +
  6559. +#define AG71XX_DEFAULT_MSG_ENABLE \
  6560. + ( NETIF_MSG_DRV \
  6561. + | NETIF_MSG_PROBE \
  6562. + | NETIF_MSG_LINK \
  6563. + | NETIF_MSG_TIMER \
  6564. + | NETIF_MSG_IFDOWN \
  6565. + | NETIF_MSG_IFUP \
  6566. + | NETIF_MSG_RX_ERR \
  6567. + | NETIF_MSG_TX_ERR )
  6568. +
  6569. +static int ag71xx_debug = -1;
  6570. +
  6571. +module_param(ag71xx_debug, int, 0);
  6572. +MODULE_PARM_DESC(ag71xx_debug, "Debug level (-1=defaults,0=none,...,16=all)");
  6573. +
  6574. +static void ag71xx_dump_dma_regs(struct ag71xx *ag)
  6575. +{
  6576. + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n",
  6577. + ag->dev->name,
  6578. + ag71xx_rr(ag, AG71XX_REG_TX_CTRL),
  6579. + ag71xx_rr(ag, AG71XX_REG_TX_DESC),
  6580. + ag71xx_rr(ag, AG71XX_REG_TX_STATUS));
  6581. +
  6582. + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n",
  6583. + ag->dev->name,
  6584. + ag71xx_rr(ag, AG71XX_REG_RX_CTRL),
  6585. + ag71xx_rr(ag, AG71XX_REG_RX_DESC),
  6586. + ag71xx_rr(ag, AG71XX_REG_RX_STATUS));
  6587. +}
  6588. +
  6589. +static void ag71xx_dump_regs(struct ag71xx *ag)
  6590. +{
  6591. + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n",
  6592. + ag->dev->name,
  6593. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1),
  6594. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  6595. + ag71xx_rr(ag, AG71XX_REG_MAC_IPG),
  6596. + ag71xx_rr(ag, AG71XX_REG_MAC_HDX),
  6597. + ag71xx_rr(ag, AG71XX_REG_MAC_MFL));
  6598. + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n",
  6599. + ag->dev->name,
  6600. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  6601. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1),
  6602. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2));
  6603. + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n",
  6604. + ag->dev->name,
  6605. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  6606. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  6607. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  6608. + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n",
  6609. + ag->dev->name,
  6610. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  6611. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  6612. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  6613. +}
  6614. +
  6615. +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
  6616. +{
  6617. + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n",
  6618. + ag->dev->name, label, intr,
  6619. + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "",
  6620. + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "",
  6621. + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "",
  6622. + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "",
  6623. + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "",
  6624. + (intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
  6625. +}
  6626. +
  6627. +static void ag71xx_ring_free(struct ag71xx_ring *ring)
  6628. +{
  6629. + kfree(ring->buf);
  6630. +
  6631. + if (ring->descs)
  6632. + dma_free_coherent(NULL, ring->size * sizeof(*ring->descs),
  6633. + ring->descs, ring->descs_dma);
  6634. +}
  6635. +
  6636. +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
  6637. +{
  6638. + int err;
  6639. +
  6640. + ring->descs = dma_alloc_coherent(NULL, size * sizeof(*ring->descs),
  6641. + &ring->descs_dma,
  6642. + GFP_ATOMIC);
  6643. + if (!ring->descs) {
  6644. + err = -ENOMEM;
  6645. + goto err;
  6646. + }
  6647. +
  6648. + ring->size = size;
  6649. +
  6650. + ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL);
  6651. + if (!ring->buf) {
  6652. + err = -ENOMEM;
  6653. + goto err;
  6654. + }
  6655. +
  6656. + return 0;
  6657. +
  6658. + err:
  6659. + return err;
  6660. +}
  6661. +
  6662. +static void ag71xx_ring_tx_clean(struct ag71xx *ag)
  6663. +{
  6664. + struct ag71xx_ring *ring = &ag->tx_ring;
  6665. + struct net_device *dev = ag->dev;
  6666. +
  6667. + while (ring->curr != ring->dirty) {
  6668. + u32 i = ring->dirty % AG71XX_TX_RING_SIZE;
  6669. +
  6670. + if (!ag71xx_desc_empty(&ring->descs[i])) {
  6671. + ring->descs[i].ctrl = 0;
  6672. + dev->stats.tx_errors++;
  6673. + }
  6674. +
  6675. + if (ring->buf[i].skb)
  6676. + dev_kfree_skb_any(ring->buf[i].skb);
  6677. +
  6678. + ring->buf[i].skb = NULL;
  6679. +
  6680. + ring->dirty++;
  6681. + }
  6682. +
  6683. + /* flush descriptors */
  6684. + wmb();
  6685. +
  6686. +}
  6687. +
  6688. +static void ag71xx_ring_tx_init(struct ag71xx *ag)
  6689. +{
  6690. + struct ag71xx_ring *ring = &ag->tx_ring;
  6691. + int i;
  6692. +
  6693. + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
  6694. + ring->descs[i].next = (u32) (ring->descs_dma +
  6695. + sizeof(*ring->descs) * ((i + 1) % AG71XX_TX_RING_SIZE));
  6696. +
  6697. + ring->descs[i].ctrl = DESC_EMPTY;
  6698. + ring->buf[i].skb = NULL;
  6699. + }
  6700. +
  6701. + /* flush descriptors */
  6702. + wmb();
  6703. +
  6704. + ring->curr = 0;
  6705. + ring->dirty = 0;
  6706. +}
  6707. +
  6708. +static void ag71xx_ring_rx_clean(struct ag71xx *ag)
  6709. +{
  6710. + struct ag71xx_ring *ring = &ag->rx_ring;
  6711. + int i;
  6712. +
  6713. + if (!ring->buf)
  6714. + return;
  6715. +
  6716. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++)
  6717. + if (ring->buf[i].skb)
  6718. + kfree_skb(ring->buf[i].skb);
  6719. +
  6720. +}
  6721. +
  6722. +static int ag71xx_ring_rx_init(struct ag71xx *ag)
  6723. +{
  6724. + struct ag71xx_ring *ring = &ag->rx_ring;
  6725. + unsigned int i;
  6726. + int ret;
  6727. +
  6728. + ret = 0;
  6729. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++)
  6730. + ring->descs[i].next = (u32) (ring->descs_dma +
  6731. + sizeof(*ring->descs) * ((i + 1) % AG71XX_RX_RING_SIZE));
  6732. +
  6733. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  6734. + struct sk_buff *skb;
  6735. +
  6736. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE);
  6737. + if (!skb) {
  6738. + ret = -ENOMEM;
  6739. + break;
  6740. + }
  6741. +
  6742. + dma_map_single(NULL, skb->data, AG71XX_RX_PKT_SIZE,
  6743. + DMA_FROM_DEVICE);
  6744. +
  6745. + skb->dev = ag->dev;
  6746. + skb_reserve(skb, AG71XX_RX_PKT_RESERVE);
  6747. +
  6748. + ring->buf[i].skb = skb;
  6749. + ring->descs[i].data = virt_to_phys(skb->data);
  6750. + ring->descs[i].ctrl = DESC_EMPTY;
  6751. + }
  6752. +
  6753. + /* flush descriptors */
  6754. + wmb();
  6755. +
  6756. + ring->curr = 0;
  6757. + ring->dirty = 0;
  6758. +
  6759. + return ret;
  6760. +}
  6761. +
  6762. +static int ag71xx_ring_rx_refill(struct ag71xx *ag)
  6763. +{
  6764. + struct ag71xx_ring *ring = &ag->rx_ring;
  6765. + unsigned int count;
  6766. +
  6767. + count = 0;
  6768. + for (; ring->curr - ring->dirty > 0; ring->dirty++) {
  6769. + unsigned int i;
  6770. +
  6771. + i = ring->dirty % AG71XX_RX_RING_SIZE;
  6772. +
  6773. + if (ring->buf[i].skb == NULL) {
  6774. + struct sk_buff *skb;
  6775. +
  6776. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE);
  6777. + if (skb == NULL)
  6778. + break;
  6779. +
  6780. + dma_map_single(NULL, skb->data, AG71XX_RX_PKT_SIZE,
  6781. + DMA_FROM_DEVICE);
  6782. +
  6783. + skb_reserve(skb, AG71XX_RX_PKT_RESERVE);
  6784. + skb->dev = ag->dev;
  6785. +
  6786. + ring->buf[i].skb = skb;
  6787. + ring->descs[i].data = virt_to_phys(skb->data);
  6788. + }
  6789. +
  6790. + ring->descs[i].ctrl = DESC_EMPTY;
  6791. + count++;
  6792. + }
  6793. +
  6794. + /* flush descriptors */
  6795. + wmb();
  6796. +
  6797. + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count);
  6798. +
  6799. + return count;
  6800. +}
  6801. +
  6802. +static int ag71xx_rings_init(struct ag71xx *ag)
  6803. +{
  6804. + int ret;
  6805. +
  6806. + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
  6807. + if (ret)
  6808. + return ret;
  6809. +
  6810. + ag71xx_ring_tx_init(ag);
  6811. +
  6812. + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
  6813. + if (ret)
  6814. + return ret;
  6815. +
  6816. + ret = ag71xx_ring_rx_init(ag);
  6817. + return ret;
  6818. +}
  6819. +
  6820. +static void ag71xx_rings_cleanup(struct ag71xx *ag)
  6821. +{
  6822. + ag71xx_ring_rx_clean(ag);
  6823. + ag71xx_ring_free(&ag->rx_ring);
  6824. +
  6825. + ag71xx_ring_tx_clean(ag);
  6826. + ag71xx_ring_free(&ag->tx_ring);
  6827. +}
  6828. +
  6829. +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
  6830. +{
  6831. + u32 t;
  6832. +
  6833. + t = (((u32) mac[0]) << 24) | (((u32) mac[1]) << 16)
  6834. + | (((u32) mac[2]) << 8) | ((u32) mac[3]);
  6835. +
  6836. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
  6837. +
  6838. + t = (((u32) mac[4]) << 24) | (((u32) mac[5]) << 16);
  6839. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
  6840. +}
  6841. +
  6842. +static void ag71xx_dma_reset(struct ag71xx *ag)
  6843. +{
  6844. + int i;
  6845. +
  6846. + ag71xx_dump_dma_regs(ag);
  6847. +
  6848. + /* stop RX and TX */
  6849. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  6850. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  6851. +
  6852. + /* clear descriptor addresses */
  6853. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
  6854. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
  6855. +
  6856. + /* clear pending RX/TX interrupts */
  6857. + for (i = 0; i < 256; i++) {
  6858. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  6859. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  6860. + }
  6861. +
  6862. + /* clear pending errors */
  6863. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
  6864. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
  6865. +
  6866. + if (ag71xx_rr(ag, AG71XX_REG_RX_STATUS))
  6867. + printk(KERN_ALERT "%s: unable to clear DMA Rx status\n",
  6868. + ag->dev->name);
  6869. +
  6870. + if (ag71xx_rr(ag, AG71XX_REG_TX_STATUS))
  6871. + printk(KERN_ALERT "%s: unable to clear DMA Tx status\n",
  6872. + ag->dev->name);
  6873. +
  6874. + ag71xx_dump_dma_regs(ag);
  6875. +}
  6876. +
  6877. +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
  6878. + MAC_CFG1_SRX | MAC_CFG1_STX)
  6879. +
  6880. +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
  6881. +
  6882. +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
  6883. + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
  6884. + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
  6885. + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
  6886. + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
  6887. + FIFO_CFG4_VT)
  6888. +
  6889. +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
  6890. + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
  6891. + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
  6892. + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
  6893. + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
  6894. + FIFO_CFG5_17 | FIFO_CFG5_SF)
  6895. +
  6896. +static void ag71xx_hw_init(struct ag71xx *ag)
  6897. +{
  6898. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  6899. +
  6900. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
  6901. + udelay(20);
  6902. +
  6903. + ar71xx_device_stop(pdata->reset_bit);
  6904. + mdelay(100);
  6905. + ar71xx_device_start(pdata->reset_bit);
  6906. + mdelay(100);
  6907. +
  6908. + /* setup MAC configuration registers */
  6909. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
  6910. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
  6911. + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
  6912. +
  6913. + /* setup max frame length */
  6914. + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
  6915. +
  6916. + /* setup MII interface type */
  6917. + ag71xx_mii_ctrl_set_if(ag, pdata->mii_if);
  6918. +
  6919. + /* setup FIFO configuration registers */
  6920. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
  6921. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
  6922. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
  6923. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
  6924. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
  6925. +
  6926. + ag71xx_dma_reset(ag);
  6927. +}
  6928. +
  6929. +static void ag71xx_hw_start(struct ag71xx *ag)
  6930. +{
  6931. + /* start RX engine */
  6932. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  6933. +
  6934. + /* enable interrupts */
  6935. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
  6936. +}
  6937. +
  6938. +static void ag71xx_hw_stop(struct ag71xx *ag)
  6939. +{
  6940. + /* disable all interrupts */
  6941. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
  6942. +
  6943. + ag71xx_dma_reset(ag);
  6944. +}
  6945. +
  6946. +static int ag71xx_open(struct net_device *dev)
  6947. +{
  6948. + struct ag71xx *ag = netdev_priv(dev);
  6949. + int ret;
  6950. +
  6951. + ret = ag71xx_rings_init(ag);
  6952. + if (ret)
  6953. + goto err;
  6954. +
  6955. + napi_enable(&ag->napi);
  6956. +
  6957. + netif_carrier_off(dev);
  6958. + ag71xx_phy_start(ag);
  6959. +
  6960. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);
  6961. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma);
  6962. +
  6963. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  6964. +
  6965. + ag71xx_hw_start(ag);
  6966. +
  6967. + netif_start_queue(dev);
  6968. +
  6969. + return 0;
  6970. +
  6971. + err:
  6972. + ag71xx_rings_cleanup(ag);
  6973. + return ret;
  6974. +}
  6975. +
  6976. +static int ag71xx_stop(struct net_device *dev)
  6977. +{
  6978. + struct ag71xx *ag = netdev_priv(dev);
  6979. + unsigned long flags;
  6980. +
  6981. + spin_lock_irqsave(&ag->lock, flags);
  6982. +
  6983. + netif_stop_queue(dev);
  6984. +
  6985. + ag71xx_hw_stop(ag);
  6986. +
  6987. + netif_carrier_off(dev);
  6988. + ag71xx_phy_stop(ag);
  6989. +
  6990. + napi_disable(&ag->napi);
  6991. + del_timer_sync(&ag->oom_timer);
  6992. +
  6993. + spin_unlock_irqrestore(&ag->lock, flags);
  6994. +
  6995. + ag71xx_rings_cleanup(ag);
  6996. +
  6997. + return 0;
  6998. +}
  6999. +
  7000. +static int ag71xx_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
  7001. +{
  7002. + struct ag71xx *ag = netdev_priv(dev);
  7003. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7004. + struct ag71xx_ring *ring = &ag->tx_ring;
  7005. + struct ag71xx_desc *desc;
  7006. + unsigned long flags;
  7007. + int i;
  7008. +
  7009. + i = ring->curr % AG71XX_TX_RING_SIZE;
  7010. + desc = &ring->descs[i];
  7011. +
  7012. + spin_lock_irqsave(&ag->lock, flags);
  7013. + pdata->ddr_flush();
  7014. + spin_unlock_irqrestore(&ag->lock, flags);
  7015. +
  7016. + if (!ag71xx_desc_empty(desc))
  7017. + goto err_drop;
  7018. +
  7019. + ag71xx_add_ar8216_header(ag, skb);
  7020. +
  7021. + if (skb->len <= 0) {
  7022. + DBG("%s: packet len is too small\n", ag->dev->name);
  7023. + goto err_drop;
  7024. + }
  7025. +
  7026. + dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
  7027. +
  7028. + ring->buf[i].skb = skb;
  7029. +
  7030. + /* setup descriptor fields */
  7031. + desc->data = virt_to_phys(skb->data);
  7032. + desc->ctrl = (skb->len & DESC_PKTLEN_M);
  7033. +
  7034. + /* flush descriptor */
  7035. + wmb();
  7036. +
  7037. + ring->curr++;
  7038. + if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) {
  7039. + DBG("%s: tx queue full\n", ag->dev->name);
  7040. + netif_stop_queue(dev);
  7041. + }
  7042. +
  7043. + DBG("%s: packet injected into TX queue\n", ag->dev->name);
  7044. +
  7045. + /* enable TX engine */
  7046. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
  7047. +
  7048. + dev->trans_start = jiffies;
  7049. +
  7050. + return 0;
  7051. +
  7052. + err_drop:
  7053. + dev->stats.tx_dropped++;
  7054. +
  7055. + dev_kfree_skb(skb);
  7056. + return 0;
  7057. +}
  7058. +
  7059. +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  7060. +{
  7061. + struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;
  7062. + struct ag71xx *ag = netdev_priv(dev);
  7063. + int ret;
  7064. +
  7065. + switch (cmd) {
  7066. + case SIOCETHTOOL:
  7067. + if (ag->phy_dev == NULL)
  7068. + break;
  7069. +
  7070. + spin_lock_irq(&ag->lock);
  7071. + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data);
  7072. + spin_unlock_irq(&ag->lock);
  7073. + return ret;
  7074. +
  7075. + case SIOCSIFHWADDR:
  7076. + if (copy_from_user
  7077. + (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
  7078. + return -EFAULT;
  7079. + return 0;
  7080. +
  7081. + case SIOCGIFHWADDR:
  7082. + if (copy_to_user
  7083. + (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
  7084. + return -EFAULT;
  7085. + return 0;
  7086. +
  7087. + case SIOCGMIIPHY:
  7088. + case SIOCGMIIREG:
  7089. + case SIOCSMIIREG:
  7090. + if (ag->phy_dev == NULL)
  7091. + break;
  7092. +
  7093. + return phy_mii_ioctl(ag->phy_dev, data, cmd);
  7094. +
  7095. + default:
  7096. + break;
  7097. + }
  7098. +
  7099. + return -EOPNOTSUPP;
  7100. +}
  7101. +
  7102. +static void ag71xx_oom_timer_handler(unsigned long data)
  7103. +{
  7104. + struct net_device *dev = (struct net_device *) data;
  7105. + struct ag71xx *ag = netdev_priv(dev);
  7106. +
  7107. + netif_rx_schedule(&ag->napi);
  7108. +}
  7109. +
  7110. +static void ag71xx_tx_timeout(struct net_device *dev)
  7111. +{
  7112. + struct ag71xx *ag = netdev_priv(dev);
  7113. +
  7114. + if (netif_msg_tx_err(ag))
  7115. + printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
  7116. +
  7117. + schedule_work(&ag->restart_work);
  7118. +}
  7119. +
  7120. +static void ag71xx_restart_work_func(struct work_struct *work)
  7121. +{
  7122. + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
  7123. +
  7124. + ag71xx_stop(ag->dev);
  7125. + ag71xx_open(ag->dev);
  7126. +}
  7127. +
  7128. +static void ag71xx_tx_packets(struct ag71xx *ag)
  7129. +{
  7130. + struct ag71xx_ring *ring = &ag->tx_ring;
  7131. + unsigned int sent;
  7132. +
  7133. + DBG("%s: processing TX ring\n", ag->dev->name);
  7134. +
  7135. + sent = 0;
  7136. + while (ring->dirty != ring->curr) {
  7137. + unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE;
  7138. + struct ag71xx_desc *desc = &ring->descs[i];
  7139. + struct sk_buff *skb = ring->buf[i].skb;
  7140. +
  7141. + if (!ag71xx_desc_empty(desc))
  7142. + break;
  7143. +
  7144. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  7145. +
  7146. + ag->dev->stats.tx_bytes += skb->len;
  7147. + ag->dev->stats.tx_packets++;
  7148. +
  7149. + dev_kfree_skb_any(skb);
  7150. + ring->buf[i].skb = NULL;
  7151. +
  7152. + ring->dirty++;
  7153. + sent++;
  7154. + }
  7155. +
  7156. + DBG("%s: %d packets sent out\n", ag->dev->name, sent);
  7157. +
  7158. + if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP)
  7159. + netif_wake_queue(ag->dev);
  7160. +
  7161. +}
  7162. +
  7163. +static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
  7164. +{
  7165. + struct net_device *dev = ag->dev;
  7166. + struct ag71xx_ring *ring = &ag->rx_ring;
  7167. + int done = 0;
  7168. +
  7169. + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n",
  7170. + dev->name, limit, ring->curr, ring->dirty);
  7171. +
  7172. + while (done < limit) {
  7173. + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
  7174. + struct ag71xx_desc *desc = &ring->descs[i];
  7175. + struct sk_buff *skb;
  7176. + int pktlen;
  7177. +
  7178. + if (ag71xx_desc_empty(desc))
  7179. + break;
  7180. +
  7181. + if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) {
  7182. + ag71xx_assert(0);
  7183. + break;
  7184. + }
  7185. +
  7186. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  7187. +
  7188. + skb = ring->buf[i].skb;
  7189. + pktlen = ag71xx_desc_pktlen(desc);
  7190. + pktlen -= ETH_FCS_LEN;
  7191. +
  7192. + skb_put(skb, pktlen);
  7193. +
  7194. + skb->dev = dev;
  7195. + skb->ip_summed = CHECKSUM_NONE;
  7196. +
  7197. + dev->last_rx = jiffies;
  7198. + dev->stats.rx_packets++;
  7199. + dev->stats.rx_bytes += pktlen;
  7200. +
  7201. + if (ag71xx_remove_ar8216_header(ag, skb) != 0) {
  7202. + dev->stats.rx_dropped++;
  7203. + kfree_skb(skb);
  7204. + } else {
  7205. + skb->protocol = eth_type_trans(skb, dev);
  7206. + netif_receive_skb(skb);
  7207. + }
  7208. +
  7209. + ring->buf[i].skb = NULL;
  7210. + done++;
  7211. +
  7212. + ring->curr++;
  7213. + }
  7214. +
  7215. + ag71xx_ring_rx_refill(ag);
  7216. +
  7217. + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n",
  7218. + dev->name, ring->curr, ring->dirty, done);
  7219. +
  7220. + return done;
  7221. +}
  7222. +
  7223. +static int ag71xx_poll(struct napi_struct *napi, int limit)
  7224. +{
  7225. + struct ag71xx *ag = container_of(napi, struct ag71xx, napi);
  7226. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7227. + struct net_device *dev = ag->dev;
  7228. + struct ag71xx_ring *rx_ring;
  7229. + unsigned long flags;
  7230. + u32 status;
  7231. + int done;
  7232. +
  7233. + pdata->ddr_flush();
  7234. + ag71xx_tx_packets(ag);
  7235. +
  7236. + DBG("%s: processing RX ring\n", dev->name);
  7237. + done = ag71xx_rx_packets(ag, limit);
  7238. +
  7239. + rx_ring = &ag->rx_ring;
  7240. + if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL)
  7241. + goto oom;
  7242. +
  7243. + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  7244. + if (unlikely(status & RX_STATUS_OF)) {
  7245. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
  7246. + dev->stats.rx_fifo_errors++;
  7247. +
  7248. + /* restart RX */
  7249. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  7250. + }
  7251. +
  7252. + if (done < limit) {
  7253. + if (status & RX_STATUS_PR)
  7254. + goto more;
  7255. +
  7256. + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  7257. + if (status & TX_STATUS_PS)
  7258. + goto more;
  7259. +
  7260. + DBG("%s: disable polling mode, done=%d, limit=%d\n",
  7261. + dev->name, done, limit);
  7262. +
  7263. + netif_rx_complete(napi);
  7264. +
  7265. + /* enable interrupts */
  7266. + spin_lock_irqsave(&ag->lock, flags);
  7267. + ag71xx_int_enable(ag, AG71XX_INT_POLL);
  7268. + spin_unlock_irqrestore(&ag->lock, flags);
  7269. + return done;
  7270. + }
  7271. +
  7272. + more:
  7273. + DBG("%s: stay in polling mode, done=%d, limit=%d\n",
  7274. + dev->name, done, limit);
  7275. + return done;
  7276. +
  7277. + oom:
  7278. + if (netif_msg_rx_err(ag))
  7279. + printk(KERN_DEBUG "%s: out of memory\n", dev->name);
  7280. +
  7281. + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
  7282. + netif_rx_complete(napi);
  7283. + return 0;
  7284. +}
  7285. +
  7286. +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
  7287. +{
  7288. + struct net_device *dev = dev_id;
  7289. + struct ag71xx *ag = netdev_priv(dev);
  7290. + u32 status;
  7291. +
  7292. + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
  7293. + ag71xx_dump_intr(ag, "raw", status);
  7294. +
  7295. + if (unlikely(!status))
  7296. + return IRQ_NONE;
  7297. +
  7298. + if (unlikely(status & AG71XX_INT_ERR)) {
  7299. + if (status & AG71XX_INT_TX_BE) {
  7300. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE);
  7301. + dev_err(&dev->dev, "TX BUS error\n");
  7302. + }
  7303. + if (status & AG71XX_INT_RX_BE) {
  7304. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE);
  7305. + dev_err(&dev->dev, "RX BUS error\n");
  7306. + }
  7307. + }
  7308. +
  7309. + if (likely(status & AG71XX_INT_POLL)) {
  7310. + ag71xx_int_disable(ag, AG71XX_INT_POLL);
  7311. + DBG("%s: enable polling mode\n", dev->name);
  7312. + netif_rx_schedule(&ag->napi);
  7313. + }
  7314. +
  7315. + return IRQ_HANDLED;
  7316. +}
  7317. +
  7318. +static void ag71xx_set_multicast_list(struct net_device *dev)
  7319. +{
  7320. + /* TODO */
  7321. +}
  7322. +
  7323. +static int __init ag71xx_probe(struct platform_device *pdev)
  7324. +{
  7325. + struct net_device *dev;
  7326. + struct resource *res;
  7327. + struct ag71xx *ag;
  7328. + struct ag71xx_platform_data *pdata;
  7329. + int err;
  7330. +
  7331. + pdata = pdev->dev.platform_data;
  7332. + if (!pdata) {
  7333. + dev_err(&pdev->dev, "no platform data specified\n");
  7334. + err = -ENXIO;
  7335. + goto err_out;
  7336. + }
  7337. +
  7338. + dev = alloc_etherdev(sizeof(*ag));
  7339. + if (!dev) {
  7340. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  7341. + err = -ENOMEM;
  7342. + goto err_out;
  7343. + }
  7344. +
  7345. + SET_NETDEV_DEV(dev, &pdev->dev);
  7346. +
  7347. + ag = netdev_priv(dev);
  7348. + ag->pdev = pdev;
  7349. + ag->dev = dev;
  7350. + ag->mii_bus = ag71xx_mdio_bus->mii_bus;
  7351. + ag->msg_enable = netif_msg_init(ag71xx_debug,
  7352. + AG71XX_DEFAULT_MSG_ENABLE);
  7353. + spin_lock_init(&ag->lock);
  7354. +
  7355. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base");
  7356. + if (!res) {
  7357. + dev_err(&pdev->dev, "no mac_base resource found\n");
  7358. + err = -ENXIO;
  7359. + goto err_out;
  7360. + }
  7361. +
  7362. + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1);
  7363. + if (!ag->mac_base) {
  7364. + dev_err(&pdev->dev, "unable to ioremap mac_base\n");
  7365. + err = -ENOMEM;
  7366. + goto err_free_dev;
  7367. + }
  7368. +
  7369. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base2");
  7370. + if (!res) {
  7371. + dev_err(&pdev->dev, "no mac_base2 resource found\n");
  7372. + err = -ENXIO;
  7373. + goto err_unmap_base1;
  7374. + }
  7375. +
  7376. + ag->mac_base2 = ioremap_nocache(res->start, res->end - res->start + 1);
  7377. + if (!ag->mac_base) {
  7378. + dev_err(&pdev->dev, "unable to ioremap mac_base2\n");
  7379. + err = -ENOMEM;
  7380. + goto err_unmap_base1;
  7381. + }
  7382. +
  7383. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl");
  7384. + if (!res) {
  7385. + dev_err(&pdev->dev, "no mii_ctrl resource found\n");
  7386. + err = -ENXIO;
  7387. + goto err_unmap_base2;
  7388. + }
  7389. +
  7390. + ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1);
  7391. + if (!ag->mii_ctrl) {
  7392. + dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n");
  7393. + err = -ENOMEM;
  7394. + goto err_unmap_base2;
  7395. + }
  7396. +
  7397. + dev->irq = platform_get_irq(pdev, 0);
  7398. + err = request_irq(dev->irq, ag71xx_interrupt,
  7399. + IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
  7400. + dev->name, dev);
  7401. + if (err) {
  7402. + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
  7403. + goto err_unmap_mii_ctrl;
  7404. + }
  7405. +
  7406. + dev->base_addr = (unsigned long)ag->mac_base;
  7407. + dev->open = ag71xx_open;
  7408. + dev->stop = ag71xx_stop;
  7409. + dev->hard_start_xmit = ag71xx_hard_start_xmit;
  7410. + dev->set_multicast_list = ag71xx_set_multicast_list;
  7411. + dev->do_ioctl = ag71xx_do_ioctl;
  7412. + dev->ethtool_ops = &ag71xx_ethtool_ops;
  7413. +
  7414. + dev->tx_timeout = ag71xx_tx_timeout;
  7415. + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
  7416. +
  7417. + init_timer(&ag->oom_timer);
  7418. + ag->oom_timer.data = (unsigned long) dev;
  7419. + ag->oom_timer.function = ag71xx_oom_timer_handler;
  7420. +
  7421. + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
  7422. +
  7423. + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
  7424. +
  7425. + err = register_netdev(dev);
  7426. + if (err) {
  7427. + dev_err(&pdev->dev, "unable to register net device\n");
  7428. + goto err_free_irq;
  7429. + }
  7430. +
  7431. + printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n",
  7432. + dev->name, dev->base_addr, dev->irq);
  7433. +
  7434. + ag71xx_dump_regs(ag);
  7435. +
  7436. + ag71xx_hw_init(ag);
  7437. +
  7438. + ag71xx_dump_regs(ag);
  7439. +
  7440. + /* Reset the mdio bus explicitly */
  7441. + if (ag->mii_bus) {
  7442. + mutex_lock(&ag->mii_bus->mdio_lock);
  7443. + ag->mii_bus->reset(ag->mii_bus);
  7444. + mutex_unlock(&ag->mii_bus->mdio_lock);
  7445. + }
  7446. +
  7447. + err = ag71xx_phy_connect(ag);
  7448. + if (err)
  7449. + goto err_unregister_netdev;
  7450. +
  7451. + platform_set_drvdata(pdev, dev);
  7452. +
  7453. + return 0;
  7454. +
  7455. + err_unregister_netdev:
  7456. + unregister_netdev(dev);
  7457. + err_free_irq:
  7458. + free_irq(dev->irq, dev);
  7459. + err_unmap_mii_ctrl:
  7460. + iounmap(ag->mii_ctrl);
  7461. + err_unmap_base2:
  7462. + iounmap(ag->mac_base2);
  7463. + err_unmap_base1:
  7464. + iounmap(ag->mac_base);
  7465. + err_free_dev:
  7466. + kfree(dev);
  7467. + err_out:
  7468. + platform_set_drvdata(pdev, NULL);
  7469. + return err;
  7470. +}
  7471. +
  7472. +static int __exit ag71xx_remove(struct platform_device *pdev)
  7473. +{
  7474. + struct net_device *dev = platform_get_drvdata(pdev);
  7475. +
  7476. + if (dev) {
  7477. + struct ag71xx *ag = netdev_priv(dev);
  7478. +
  7479. + ag71xx_phy_disconnect(ag);
  7480. + unregister_netdev(dev);
  7481. + free_irq(dev->irq, dev);
  7482. + iounmap(ag->mii_ctrl);
  7483. + iounmap(ag->mac_base2);
  7484. + iounmap(ag->mac_base);
  7485. + kfree(dev);
  7486. + platform_set_drvdata(pdev, NULL);
  7487. + }
  7488. +
  7489. + return 0;
  7490. +}
  7491. +
  7492. +static struct platform_driver ag71xx_driver = {
  7493. + .probe = ag71xx_probe,
  7494. + .remove = __exit_p(ag71xx_remove),
  7495. + .driver = {
  7496. + .name = AG71XX_DRV_NAME,
  7497. + }
  7498. +};
  7499. +
  7500. +static int __init ag71xx_module_init(void)
  7501. +{
  7502. + int ret;
  7503. +
  7504. + ret = ag71xx_mdio_driver_init();
  7505. + if (ret)
  7506. + goto err_out;
  7507. +
  7508. + ret = platform_driver_register(&ag71xx_driver);
  7509. + if (ret)
  7510. + goto err_mdio_exit;
  7511. +
  7512. + return 0;
  7513. +
  7514. + err_mdio_exit:
  7515. + ag71xx_mdio_driver_exit();
  7516. + err_out:
  7517. + return ret;
  7518. +}
  7519. +
  7520. +static void __exit ag71xx_module_exit(void)
  7521. +{
  7522. + platform_driver_unregister(&ag71xx_driver);
  7523. + ag71xx_mdio_driver_exit();
  7524. +}
  7525. +
  7526. +module_init(ag71xx_module_init);
  7527. +module_exit(ag71xx_module_exit);
  7528. +
  7529. +MODULE_VERSION(AG71XX_DRV_VERSION);
  7530. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  7531. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  7532. +MODULE_LICENSE("GPL v2");
  7533. +MODULE_ALIAS("platform:" AG71XX_DRV_NAME);
  7534. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_mdio.c
  7535. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100
  7536. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_mdio.c 2009-04-13 14:27:34.827084882 +0200
  7537. @@ -0,0 +1,233 @@
  7538. +/*
  7539. + * Atheros AR71xx built-in ethernet mac driver
  7540. + *
  7541. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7542. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7543. + *
  7544. + * Based on Atheros' AG7100 driver
  7545. + *
  7546. + * This program is free software; you can redistribute it and/or modify it
  7547. + * under the terms of the GNU General Public License version 2 as published
  7548. + * by the Free Software Foundation.
  7549. + */
  7550. +
  7551. +#include "ag71xx.h"
  7552. +
  7553. +#define AG71XX_MDIO_RETRY 1000
  7554. +#define AG71XX_MDIO_DELAY 5
  7555. +
  7556. +struct ag71xx_mdio *ag71xx_mdio_bus;
  7557. +
  7558. +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg,
  7559. + u32 value)
  7560. +{
  7561. + __raw_writel(value, am->mdio_base + reg - AG71XX_REG_MII_CFG);
  7562. +}
  7563. +
  7564. +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg)
  7565. +{
  7566. + return __raw_readl(am->mdio_base + reg - AG71XX_REG_MII_CFG);
  7567. +}
  7568. +
  7569. +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
  7570. +{
  7571. + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n",
  7572. + am->mii_bus->name,
  7573. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG),
  7574. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD),
  7575. + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR));
  7576. + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n",
  7577. + am->mii_bus->name,
  7578. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL),
  7579. + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS),
  7580. + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
  7581. +}
  7582. +
  7583. +static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
  7584. +{
  7585. + int ret;
  7586. + int i;
  7587. +
  7588. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  7589. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  7590. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  7591. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ);
  7592. +
  7593. + i = AG71XX_MDIO_RETRY;
  7594. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  7595. + if (i-- == 0) {
  7596. + printk(KERN_ERR "%s: mii_read timed out\n",
  7597. + am->mii_bus->name);
  7598. + ret = 0xffff;
  7599. + goto out;
  7600. + }
  7601. + udelay(AG71XX_MDIO_DELAY);
  7602. + }
  7603. +
  7604. + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff;
  7605. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  7606. +
  7607. + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
  7608. +
  7609. + out:
  7610. + return ret;
  7611. +}
  7612. +
  7613. +static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am,
  7614. + int addr, int reg, u16 val)
  7615. +{
  7616. + int i;
  7617. +
  7618. + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
  7619. +
  7620. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  7621. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  7622. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val);
  7623. +
  7624. + i = AG71XX_MDIO_RETRY;
  7625. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  7626. + if (i-- == 0) {
  7627. + printk(KERN_ERR "%s: mii_write timed out\n",
  7628. + am->mii_bus->name);
  7629. + break;
  7630. + }
  7631. + udelay(AG71XX_MDIO_DELAY);
  7632. + }
  7633. +}
  7634. +
  7635. +static int ag71xx_mdio_reset(struct mii_bus *bus)
  7636. +{
  7637. + struct ag71xx_mdio *am = bus->priv;
  7638. +
  7639. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, MII_CFG_RESET);
  7640. + udelay(100);
  7641. +
  7642. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_28);
  7643. + udelay(100);
  7644. +
  7645. + return 0;
  7646. +}
  7647. +
  7648. +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
  7649. +{
  7650. + struct ag71xx_mdio *am = bus->priv;
  7651. +
  7652. + return ag71xx_mdio_mii_read(am, addr, reg);
  7653. +}
  7654. +
  7655. +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
  7656. +{
  7657. + struct ag71xx_mdio *am = bus->priv;
  7658. +
  7659. + ag71xx_mdio_mii_write(am, addr, reg, val);
  7660. + return 0;
  7661. +}
  7662. +
  7663. +static int __init ag71xx_mdio_probe(struct platform_device *pdev)
  7664. +{
  7665. + struct ag71xx_mdio_platform_data *pdata;
  7666. + struct ag71xx_mdio *am;
  7667. + struct resource *res;
  7668. + int i;
  7669. + int err;
  7670. +
  7671. + if (ag71xx_mdio_bus)
  7672. + return -EBUSY;
  7673. +
  7674. + am = kzalloc(sizeof(*am), GFP_KERNEL);
  7675. + if (!am) {
  7676. + err = -ENOMEM;
  7677. + goto err_out;
  7678. + }
  7679. +
  7680. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  7681. + if (!res) {
  7682. + dev_err(&pdev->dev, "no iomem resource found\n");
  7683. + err = -ENXIO;
  7684. + goto err_out;
  7685. + }
  7686. +
  7687. + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);
  7688. + if (!am->mdio_base) {
  7689. + dev_err(&pdev->dev, "unable to ioremap registers\n");
  7690. + err = -ENOMEM;
  7691. + goto err_free_mdio;
  7692. + }
  7693. +
  7694. + am->mii_bus = mdiobus_alloc();
  7695. + if (am->mii_bus == NULL) {
  7696. + err = -ENOMEM;
  7697. + goto err_iounmap;
  7698. + }
  7699. +
  7700. + am->mii_bus->name = "ag71xx_mdio";
  7701. + am->mii_bus->read = ag71xx_mdio_read;
  7702. + am->mii_bus->write = ag71xx_mdio_write;
  7703. + am->mii_bus->reset = ag71xx_mdio_reset;
  7704. + am->mii_bus->irq = am->mii_irq;
  7705. + am->mii_bus->priv = am;
  7706. + am->mii_bus->parent = &pdev->dev;
  7707. + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
  7708. +
  7709. + pdata = pdev->dev.platform_data;
  7710. + if (pdata)
  7711. + am->mii_bus->phy_mask = pdata->phy_mask;
  7712. +
  7713. + for (i = 0; i < PHY_MAX_ADDR; i++)
  7714. + am->mii_irq[i] = PHY_POLL;
  7715. +
  7716. + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0);
  7717. +
  7718. + err = mdiobus_register(am->mii_bus);
  7719. + if (err)
  7720. + goto err_free_bus;
  7721. +
  7722. + ag71xx_mdio_dump_regs(am);
  7723. +
  7724. + platform_set_drvdata(pdev, am);
  7725. + ag71xx_mdio_bus = am;
  7726. + return 0;
  7727. +
  7728. + err_free_bus:
  7729. + mdiobus_free(am->mii_bus);
  7730. + err_iounmap:
  7731. + iounmap(am->mdio_base);
  7732. + err_free_mdio:
  7733. + kfree(am);
  7734. + err_out:
  7735. + return err;
  7736. +}
  7737. +
  7738. +static int __exit ag71xx_mdio_remove(struct platform_device *pdev)
  7739. +{
  7740. + struct ag71xx_mdio *am = platform_get_drvdata(pdev);
  7741. +
  7742. + if (am) {
  7743. + ag71xx_mdio_bus = NULL;
  7744. + mdiobus_unregister(am->mii_bus);
  7745. + mdiobus_free(am->mii_bus);
  7746. + iounmap(am->mdio_base);
  7747. + kfree(am);
  7748. + platform_set_drvdata(pdev, NULL);
  7749. + }
  7750. +
  7751. + return 0;
  7752. +}
  7753. +
  7754. +static struct platform_driver ag71xx_mdio_driver = {
  7755. + .probe = ag71xx_mdio_probe,
  7756. + .remove = __exit_p(ag71xx_mdio_remove),
  7757. + .driver = {
  7758. + .name = "ag71xx-mdio",
  7759. + }
  7760. +};
  7761. +
  7762. +int ag71xx_mdio_driver_init(void)
  7763. +{
  7764. + return platform_driver_register(&ag71xx_mdio_driver);
  7765. +}
  7766. +
  7767. +void ag71xx_mdio_driver_exit(void)
  7768. +{
  7769. + platform_driver_unregister(&ag71xx_mdio_driver);
  7770. +}
  7771. diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_phy.c
  7772. --- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100
  7773. +++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_phy.c 2009-04-13 14:27:34.827084882 +0200
  7774. @@ -0,0 +1,287 @@
  7775. +/*
  7776. + * Atheros AR71xx built-in ethernet mac driver
  7777. + *
  7778. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7779. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7780. + *
  7781. + * Based on Atheros' AG7100 driver
  7782. + *
  7783. + * This program is free software; you can redistribute it and/or modify it
  7784. + * under the terms of the GNU General Public License version 2 as published
  7785. + * by the Free Software Foundation.
  7786. + */
  7787. +
  7788. +#include "ag71xx.h"
  7789. +
  7790. +static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
  7791. +{
  7792. + switch (ag->speed) {
  7793. + case SPEED_1000:
  7794. + return "1000";
  7795. + case SPEED_100:
  7796. + return "100";
  7797. + case SPEED_10:
  7798. + return "10";
  7799. + }
  7800. +
  7801. + return "?";
  7802. +}
  7803. +
  7804. +#define AR71XX_PLL_VAL_1000 0x00110000
  7805. +#define AR71XX_PLL_VAL_100 0x00001099
  7806. +#define AR71XX_PLL_VAL_10 0x00991099
  7807. +
  7808. +#define AR91XX_PLL_VAL_1000 0x1a000000
  7809. +#define AR91XX_PLL_VAL_100 0x13000a44
  7810. +#define AR91XX_PLL_VAL_10 0x00441099
  7811. +
  7812. +static void ag71xx_phy_link_update(struct ag71xx *ag)
  7813. +{
  7814. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7815. + u32 cfg2;
  7816. + u32 ifctl;
  7817. + u32 pll;
  7818. + u32 fifo5;
  7819. + u32 mii_speed;
  7820. +
  7821. + if (!ag->link) {
  7822. + netif_carrier_off(ag->dev);
  7823. + if (netif_msg_link(ag))
  7824. + printk(KERN_INFO "%s: link down\n", ag->dev->name);
  7825. + return;
  7826. + }
  7827. +
  7828. + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
  7829. + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
  7830. + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
  7831. +
  7832. + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
  7833. + ifctl &= ~(MAC_IFCTL_SPEED);
  7834. +
  7835. + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
  7836. + fifo5 &= ~FIFO_CFG5_BM;
  7837. +
  7838. + switch (ag->speed) {
  7839. + case SPEED_1000:
  7840. + mii_speed = MII_CTRL_SPEED_1000;
  7841. + cfg2 |= MAC_CFG2_IF_1000;
  7842. + pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_1000
  7843. + : AR71XX_PLL_VAL_1000;
  7844. + fifo5 |= FIFO_CFG5_BM;
  7845. + break;
  7846. + case SPEED_100:
  7847. + mii_speed = MII_CTRL_SPEED_100;
  7848. + cfg2 |= MAC_CFG2_IF_10_100;
  7849. + ifctl |= MAC_IFCTL_SPEED;
  7850. + pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_100
  7851. + : AR71XX_PLL_VAL_100;
  7852. + break;
  7853. + case SPEED_10:
  7854. + mii_speed = MII_CTRL_SPEED_10;
  7855. + cfg2 |= MAC_CFG2_IF_10_100;
  7856. + pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_10
  7857. + : AR71XX_PLL_VAL_10;
  7858. + break;
  7859. + default:
  7860. + BUG();
  7861. + return;
  7862. + }
  7863. +
  7864. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3,
  7865. + pdata->is_ar91xx ? 0x780fff : 0x008001ff);
  7866. + pdata->set_pll(pll);
  7867. + ag71xx_mii_ctrl_set_speed(ag, mii_speed);
  7868. +
  7869. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
  7870. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
  7871. + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
  7872. +
  7873. + netif_carrier_on(ag->dev);
  7874. + if (netif_msg_link(ag))
  7875. + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
  7876. + ag->dev->name,
  7877. + ag71xx_speed_str(ag),
  7878. + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half");
  7879. +
  7880. + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
  7881. + ag->dev->name,
  7882. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  7883. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  7884. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  7885. +
  7886. + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
  7887. + ag->dev->name,
  7888. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  7889. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  7890. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  7891. +
  7892. + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
  7893. + ag->dev->name,
  7894. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  7895. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  7896. + ag71xx_mii_ctrl_rr(ag));
  7897. +}
  7898. +
  7899. +static void ag71xx_phy_link_adjust(struct net_device *dev)
  7900. +{
  7901. + struct ag71xx *ag = netdev_priv(dev);
  7902. + struct phy_device *phydev = ag->phy_dev;
  7903. + unsigned long flags;
  7904. + int status_change = 0;
  7905. +
  7906. + spin_lock_irqsave(&ag->lock, flags);
  7907. +
  7908. + if (phydev->link) {
  7909. + if (ag->duplex != phydev->duplex
  7910. + || ag->speed != phydev->speed) {
  7911. + status_change = 1;
  7912. + }
  7913. + }
  7914. +
  7915. + if (phydev->link != ag->link)
  7916. + status_change = 1;
  7917. +
  7918. + ag->link = phydev->link;
  7919. + ag->duplex = phydev->duplex;
  7920. + ag->speed = phydev->speed;
  7921. +
  7922. + if (status_change)
  7923. + ag71xx_phy_link_update(ag);
  7924. +
  7925. + spin_unlock_irqrestore(&ag->lock, flags);
  7926. +}
  7927. +
  7928. +void ag71xx_phy_start(struct ag71xx *ag)
  7929. +{
  7930. + if (ag->phy_dev) {
  7931. + phy_start(ag->phy_dev);
  7932. + } else {
  7933. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7934. +
  7935. + ag->duplex = pdata->duplex;
  7936. + ag->speed = pdata->speed;
  7937. + ag->link = 1;
  7938. + ag71xx_phy_link_update(ag);
  7939. + }
  7940. +}
  7941. +
  7942. +void ag71xx_phy_stop(struct ag71xx *ag)
  7943. +{
  7944. + if (ag->phy_dev) {
  7945. + phy_stop(ag->phy_dev);
  7946. + } else {
  7947. + ag->duplex = -1;
  7948. + ag->link = 0;
  7949. + ag->speed = 0;
  7950. + ag71xx_phy_link_update(ag);
  7951. + }
  7952. +}
  7953. +
  7954. +static int ag71xx_phy_connect_fixed(struct ag71xx *ag)
  7955. +{
  7956. + struct net_device *dev = ag->dev;
  7957. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7958. + int ret = 0;
  7959. +
  7960. + /* use fixed settings */
  7961. + switch (pdata->speed) {
  7962. + case SPEED_10:
  7963. + case SPEED_100:
  7964. + case SPEED_1000:
  7965. + break;
  7966. + default:
  7967. + printk(KERN_ERR "%s: invalid speed specified\n",
  7968. + dev->name);
  7969. + ret = -EINVAL;
  7970. + break;
  7971. + }
  7972. +
  7973. + return ret;
  7974. +}
  7975. +
  7976. +static int ag71xx_phy_connect_multi(struct ag71xx *ag)
  7977. +{
  7978. + struct net_device *dev = ag->dev;
  7979. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  7980. + struct phy_device *phydev = NULL;
  7981. + int phy_count = 0;
  7982. + int phy_addr;
  7983. + int ret = 0;
  7984. +
  7985. + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
  7986. + if (!(pdata->phy_mask & (1 << phy_addr)))
  7987. + continue;
  7988. +
  7989. + if (ag->mii_bus->phy_map[phy_addr] == NULL)
  7990. + continue;
  7991. +
  7992. + DBG("%s: PHY found at %s, uid=%08x\n",
  7993. + dev->name,
  7994. + ag->mii_bus->phy_map[phy_addr]->dev.bus_id,
  7995. + ag->mii_bus->phy_map[phy_addr]->phy_id);
  7996. +
  7997. + if (phydev == NULL)
  7998. + phydev = ag->mii_bus->phy_map[phy_addr];
  7999. +
  8000. + phy_count++;
  8001. + }
  8002. +
  8003. + switch (phy_count) {
  8004. + case 0:
  8005. + printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",
  8006. + dev->name, pdata->phy_mask);
  8007. + ret = -ENODEV;
  8008. + break;
  8009. + case 1:
  8010. + ag->phy_dev = phy_connect(dev, phydev->dev.bus_id,
  8011. + &ag71xx_phy_link_adjust, 0, pdata->phy_if_mode);
  8012. +
  8013. + if (IS_ERR(ag->phy_dev)) {
  8014. + printk(KERN_ERR "%s: could not connect to PHY at %s\n",
  8015. + dev->name, phydev->dev.bus_id);
  8016. + return PTR_ERR(ag->phy_dev);
  8017. + }
  8018. +
  8019. + /* mask with MAC supported features */
  8020. + if (pdata->has_gbit)
  8021. + phydev->supported &= PHY_GBIT_FEATURES;
  8022. + else
  8023. + phydev->supported &= PHY_BASIC_FEATURES;
  8024. +
  8025. + phydev->advertising = phydev->supported;
  8026. +
  8027. + printk(KERN_DEBUG "%s: connected to PHY at %s "
  8028. + "[uid=%08x, driver=%s]\n",
  8029. + dev->name, phydev->dev.bus_id,
  8030. + phydev->phy_id, phydev->drv->name);
  8031. +
  8032. + ag->link = 0;
  8033. + ag->speed = 0;
  8034. + ag->duplex = -1;
  8035. + break;
  8036. +
  8037. + default:
  8038. + printk(KERN_DEBUG "%s: connected to %d PHYs\n",
  8039. + dev->name, phy_count);
  8040. + ret = ag71xx_phy_connect_fixed(ag);
  8041. + break;
  8042. + }
  8043. +
  8044. + return ret;
  8045. +}
  8046. +
  8047. +int ag71xx_phy_connect(struct ag71xx *ag)
  8048. +{
  8049. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  8050. +
  8051. + if (pdata->phy_mask)
  8052. + return ag71xx_phy_connect_multi(ag);
  8053. +
  8054. + return ag71xx_phy_connect_fixed(ag);
  8055. +}
  8056. +
  8057. +void ag71xx_phy_disconnect(struct ag71xx *ag)
  8058. +{
  8059. + if (ag->phy_dev)
  8060. + phy_disconnect(ag->phy_dev);
  8061. +}
  8062. diff -Nur linux-2.6.29.1.orig/drivers/net/phy/micrel.c linux-2.6.29.1/drivers/net/phy/micrel.c
  8063. --- linux-2.6.29.1.orig/drivers/net/phy/micrel.c 1970-01-01 01:00:00.000000000 +0100
  8064. +++ linux-2.6.29.1/drivers/net/phy/micrel.c 2009-04-13 14:27:34.831085671 +0200
  8065. @@ -0,0 +1,82 @@
  8066. +/*
  8067. + * Driver for Micrel/Kendin PHYs
  8068. + *
  8069. + * Copyright (c) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8070. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8071. + *
  8072. + * This program is free software; you can redistribute it and/or modify it
  8073. + * under the terms of the GNU General Public License version 2 as published
  8074. + * by the Free Software Foundation.
  8075. + *
  8076. + */
  8077. +
  8078. +#include <linux/delay.h>
  8079. +#include <linux/skbuff.h>
  8080. +#include <linux/phy.h>
  8081. +
  8082. +#define KSZ_REG_INT_CTRL 0x1b
  8083. +
  8084. +#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */
  8085. +#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */
  8086. +#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */
  8087. +
  8088. +#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN)
  8089. +
  8090. +static int ksz8041_ack_interrupt(struct phy_device *phydev)
  8091. +{
  8092. + int err;
  8093. +
  8094. + err = phy_read(phydev, KSZ_REG_INT_CTRL);
  8095. +
  8096. + return (err < 0) ? err : 0;
  8097. +}
  8098. +
  8099. +static int ksz8041_config_intr(struct phy_device *phydev)
  8100. +{
  8101. + int err;
  8102. +
  8103. + if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  8104. + err = phy_write(phydev, KSZ_REG_INT_CTRL,
  8105. + KSZ_INT_INIT);
  8106. + else
  8107. + err = phy_write(phydev, KSZ_REG_INT_CTRL, 0);
  8108. +
  8109. + return err;
  8110. +}
  8111. +
  8112. +static struct phy_driver ksz8041_phy_driver = {
  8113. + .phy_id = 0x00221512,
  8114. + .name = "Micrel KSZ8041",
  8115. + .phy_id_mask = 0x001fffff,
  8116. + .features = PHY_BASIC_FEATURES,
  8117. + .flags = PHY_HAS_INTERRUPT,
  8118. + .config_aneg = genphy_config_aneg,
  8119. + .read_status = genphy_read_status,
  8120. + .ack_interrupt = ksz8041_ack_interrupt,
  8121. + .config_intr = ksz8041_config_intr,
  8122. + .driver = {
  8123. + .owner = THIS_MODULE,
  8124. + },
  8125. +};
  8126. +
  8127. +static int __init micrel_phy_init(void)
  8128. +{
  8129. + return phy_driver_register(&ksz8041_phy_driver);
  8130. +}
  8131. +
  8132. +static void __exit micrel_phy_exit(void)
  8133. +{
  8134. + phy_driver_unregister(&ksz8041_phy_driver);
  8135. +}
  8136. +
  8137. +#ifdef MODULE
  8138. +module_init(micrel_phy_init);
  8139. +module_exit(micrel_phy_exit);
  8140. +#else
  8141. +subsys_initcall(micrel_phy_init);
  8142. +#endif
  8143. +
  8144. +MODULE_DESCRIPTION("Micrel/Kendin PHY driver");
  8145. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  8146. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  8147. +MODULE_LICENSE("GPL v2");
  8148. diff -Nur linux-2.6.29.1.orig/drivers/net/phy/phy.c linux-2.6.29.1/drivers/net/phy/phy.c
  8149. --- linux-2.6.29.1.orig/drivers/net/phy/phy.c 2009-04-02 22:55:27.000000000 +0200
  8150. +++ linux-2.6.29.1/drivers/net/phy/phy.c 2009-04-13 17:29:36.946673592 +0200
  8151. @@ -299,6 +299,50 @@
  8152. }
  8153. EXPORT_SYMBOL(phy_ethtool_gset);
  8154. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  8155. +{
  8156. + u32 cmd;
  8157. + int tmp;
  8158. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  8159. + struct ethtool_value edata = { ETHTOOL_GLINK };
  8160. +
  8161. + if (get_user(cmd, (u32 *) useraddr))
  8162. + return -EFAULT;
  8163. +
  8164. + switch (cmd) {
  8165. + case ETHTOOL_GSET:
  8166. + phy_ethtool_gset(phydev, &ecmd);
  8167. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  8168. + return -EFAULT;
  8169. + return 0;
  8170. +
  8171. + case ETHTOOL_SSET:
  8172. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  8173. + return -EFAULT;
  8174. + return phy_ethtool_sset(phydev, &ecmd);
  8175. +
  8176. + case ETHTOOL_NWAY_RST:
  8177. + /* if autoneg is off, it's an error */
  8178. + tmp = phy_read(phydev, MII_BMCR);
  8179. + if (tmp & BMCR_ANENABLE) {
  8180. + tmp |= (BMCR_ANRESTART);
  8181. + phy_write(phydev, MII_BMCR, tmp);
  8182. + return 0;
  8183. + }
  8184. + return -EINVAL;
  8185. +
  8186. + case ETHTOOL_GLINK:
  8187. + edata.data = (phy_read(phydev,
  8188. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  8189. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  8190. + return -EFAULT;
  8191. + return 0;
  8192. + }
  8193. +
  8194. + return -EOPNOTSUPP;
  8195. +}
  8196. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  8197. +
  8198. /**
  8199. * phy_mii_ioctl - generic PHY MII ioctl interface
  8200. * @phydev: the phy_device struct
  8201. @@ -355,8 +399,8 @@
  8202. }
  8203. phy_write(phydev, mii_data->reg_num, val);
  8204. -
  8205. - if (mii_data->reg_num == MII_BMCR
  8206. +
  8207. + if (mii_data->reg_num == MII_BMCR
  8208. && val & BMCR_RESET
  8209. && phydev->drv->config_init) {
  8210. phy_scan_fixups(phydev);
  8211. @@ -476,7 +520,7 @@
  8212. int idx;
  8213. idx = phy_find_setting(phydev->speed, phydev->duplex);
  8214. -
  8215. +
  8216. idx++;
  8217. idx = phy_find_valid(idx, phydev->supported);
  8218. diff -Nur linux-2.6.29.1.orig/drivers/spi/Kconfig linux-2.6.29.1/drivers/spi/Kconfig
  8219. --- linux-2.6.29.1.orig/drivers/spi/Kconfig 2009-04-02 22:55:27.000000000 +0200
  8220. +++ linux-2.6.29.1/drivers/spi/Kconfig 2009-04-13 14:27:34.831085671 +0200
  8221. @@ -53,6 +53,13 @@
  8222. comment "SPI Master Controller Drivers"
  8223. +config SPI_AR71XX
  8224. + tristate "Atheros AR71xx SPI Controller"
  8225. + depends on SPI_MASTER && ATHEROS_AR71XX
  8226. + select SPI_BITBANG
  8227. + help
  8228. + This is the SPI contoller driver for Atheros AR71xx.
  8229. +
  8230. config SPI_ATMEL
  8231. tristate "Atmel SPI Controller"
  8232. depends on (ARCH_AT91 || AVR32)
  8233. diff -Nur linux-2.6.29.1.orig/drivers/spi/Makefile linux-2.6.29.1/drivers/spi/Makefile
  8234. --- linux-2.6.29.1.orig/drivers/spi/Makefile 2009-04-02 22:55:27.000000000 +0200
  8235. +++ linux-2.6.29.1/drivers/spi/Makefile 2009-04-13 14:27:34.835086738 +0200
  8236. @@ -11,6 +11,7 @@
  8237. obj-$(CONFIG_SPI_MASTER) += spi.o
  8238. # SPI master controller drivers (bus)
  8239. +obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
  8240. obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
  8241. obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
  8242. obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
  8243. diff -Nur linux-2.6.29.1.orig/drivers/spi/ar71xx_spi.c linux-2.6.29.1/drivers/spi/ar71xx_spi.c
  8244. --- linux-2.6.29.1.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  8245. +++ linux-2.6.29.1/drivers/spi/ar71xx_spi.c 2009-04-13 14:27:34.855087329 +0200
  8246. @@ -0,0 +1,240 @@
  8247. +/*
  8248. + * Atheros AR71xx SPI Controller driver
  8249. + *
  8250. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8251. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8252. + *
  8253. + * This program is free software; you can redistribute it and/or modify
  8254. + * it under the terms of the GNU General Public License version 2 as
  8255. + * published by the Free Software Foundation.
  8256. + *
  8257. + */
  8258. +
  8259. +#include <linux/kernel.h>
  8260. +#include <linux/init.h>
  8261. +#include <linux/delay.h>
  8262. +#include <linux/spinlock.h>
  8263. +#include <linux/workqueue.h>
  8264. +#include <linux/platform_device.h>
  8265. +#include <linux/io.h>
  8266. +#include <linux/spi/spi.h>
  8267. +#include <linux/spi/spi_bitbang.h>
  8268. +#include <linux/bitops.h>
  8269. +
  8270. +#include <asm/mach-ar71xx/ar71xx.h>
  8271. +#include <asm/mach-ar71xx/platform.h>
  8272. +
  8273. +#define DRV_DESC "Atheros AR71xx SPI Controller driver"
  8274. +#define DRV_VERSION "0.2.2"
  8275. +#define DRV_NAME "ar71xx-spi"
  8276. +
  8277. +#undef PER_BIT_READ
  8278. +
  8279. +struct ar71xx_spi {
  8280. + struct spi_bitbang bitbang;
  8281. + u32 ioc_base;
  8282. + u32 reg_ctrl;
  8283. +
  8284. + void __iomem *base;
  8285. +
  8286. + struct platform_device *pdev;
  8287. + u32 (*get_ioc_base)(u8 chip_select, int cs_high,
  8288. + int is_on);
  8289. +};
  8290. +
  8291. +static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  8292. +{
  8293. + return __raw_readl(sp->base + reg);
  8294. +}
  8295. +
  8296. +static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  8297. +{
  8298. + __raw_writel(val, sp->base + reg);
  8299. +}
  8300. +
  8301. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  8302. +{
  8303. + return spi_master_get_devdata(spi->master);
  8304. +}
  8305. +
  8306. +static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  8307. +{
  8308. + u32 ret;
  8309. +
  8310. + if (is_on == AR71XX_SPI_CS_INACTIVE)
  8311. + ret = SPI_IOC_CS_ALL;
  8312. + else
  8313. + ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select);
  8314. +
  8315. + return ret;
  8316. +}
  8317. +
  8318. +static void ar71xx_spi_chipselect(struct spi_device *spi, int value)
  8319. +{
  8320. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  8321. + void __iomem *base = sp->base;
  8322. + u32 ioc_base;
  8323. +
  8324. + switch (value) {
  8325. + case BITBANG_CS_INACTIVE:
  8326. + ioc_base = sp->get_ioc_base(spi->chip_select,
  8327. + (spi->mode & SPI_CS_HIGH) != 0,
  8328. + AR71XX_SPI_CS_INACTIVE);
  8329. +
  8330. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  8331. + __raw_writel(sp->reg_ctrl, base + SPI_REG_CTRL);
  8332. + __raw_writel(0, base + SPI_REG_FS);
  8333. + break;
  8334. +
  8335. + case BITBANG_CS_ACTIVE:
  8336. + ioc_base = sp->get_ioc_base(spi->chip_select,
  8337. + (spi->mode & SPI_CS_HIGH) != 0,
  8338. + AR71XX_SPI_CS_ACTIVE);
  8339. +
  8340. + __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS);
  8341. + /* TODO: setup speed */
  8342. + __raw_writel(0x43, base + SPI_REG_CTRL);
  8343. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  8344. + sp->ioc_base = ioc_base;
  8345. + break;
  8346. + }
  8347. +}
  8348. +
  8349. +static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  8350. + u32 word, u8 bits)
  8351. +{
  8352. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  8353. + void __iomem *base = sp->base;
  8354. + u32 ioc = sp->ioc_base;
  8355. + u32 ret;
  8356. +
  8357. + /* clock starts at inactive polarity */
  8358. + for (word <<= (32 - bits); likely(bits); bits--) {
  8359. + u32 out;
  8360. +
  8361. + if (word & (1 << 31))
  8362. + out = ioc | SPI_IOC_DO;
  8363. + else
  8364. + out = ioc & ~SPI_IOC_DO;
  8365. +
  8366. + /* setup MSB (to slave) on trailing edge */
  8367. + __raw_writel(out, base + SPI_REG_IOC);
  8368. +
  8369. + __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC);
  8370. +
  8371. + word <<= 1;
  8372. +
  8373. +#ifdef PER_BIT_READ
  8374. + /* sample MSB (from slave) on leading edge */
  8375. + ret = __raw_readl(base + SPI_REG_RDS);
  8376. + __raw_writel(out, base + SPI_REG_IOC);
  8377. +#endif
  8378. +
  8379. + }
  8380. +
  8381. +#ifndef PER_BIT_READ
  8382. + ret = __raw_readl(base + SPI_REG_RDS);
  8383. +#endif
  8384. + return ret;
  8385. +}
  8386. +
  8387. +static int ar71xx_spi_probe(struct platform_device *pdev)
  8388. +{
  8389. + struct spi_master *master;
  8390. + struct ar71xx_spi *sp;
  8391. + struct ar71xx_spi_platform_data *pdata;
  8392. + struct resource *r;
  8393. + int ret;
  8394. +
  8395. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  8396. + if (master == NULL) {
  8397. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  8398. + return -ENOMEM;
  8399. + }
  8400. +
  8401. + sp = spi_master_get_devdata(master);
  8402. + platform_set_drvdata(pdev, sp);
  8403. +
  8404. + pdata = pdev->dev.platform_data;
  8405. +
  8406. + sp->bitbang.master = spi_master_get(master);
  8407. + sp->bitbang.chipselect = ar71xx_spi_chipselect;
  8408. + sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
  8409. +
  8410. + sp->get_ioc_base = ar71xx_spi_get_ioc_base;
  8411. + if (pdata) {
  8412. + sp->bitbang.master->bus_num = pdata->bus_num;
  8413. + sp->bitbang.master->num_chipselect = pdata->num_chipselect;
  8414. + if (pdata->get_ioc_base)
  8415. + sp->get_ioc_base = pdata->get_ioc_base;
  8416. + } else {
  8417. + sp->bitbang.master->bus_num = 0;
  8418. + sp->bitbang.master->num_chipselect = 3;
  8419. + }
  8420. +
  8421. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  8422. + if (r == NULL) {
  8423. + ret = -ENOENT;
  8424. + goto err1;
  8425. + }
  8426. +
  8427. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  8428. + if (!sp->base) {
  8429. + ret = -ENXIO;
  8430. + goto err1;
  8431. + }
  8432. +
  8433. + sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_IOC);
  8434. +
  8435. + ret = spi_bitbang_start(&sp->bitbang);
  8436. + if (!ret)
  8437. + return 0;
  8438. +
  8439. + iounmap(sp->base);
  8440. +err1:
  8441. + platform_set_drvdata(pdev, NULL);
  8442. + spi_master_put(sp->bitbang.master);
  8443. +
  8444. + return ret;
  8445. +}
  8446. +
  8447. +static int ar71xx_spi_remove(struct platform_device *pdev)
  8448. +{
  8449. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  8450. +
  8451. + spi_bitbang_stop(&sp->bitbang);
  8452. + iounmap(sp->base);
  8453. + platform_set_drvdata(pdev, NULL);
  8454. + spi_master_put(sp->bitbang.master);
  8455. +
  8456. + return 0;
  8457. +}
  8458. +
  8459. +static struct platform_driver ar71xx_spi_drv = {
  8460. + .probe = ar71xx_spi_probe,
  8461. + .remove = ar71xx_spi_remove,
  8462. + .driver = {
  8463. + .name = DRV_NAME,
  8464. + .owner = THIS_MODULE,
  8465. + },
  8466. +};
  8467. +
  8468. +static int __init ar71xx_spi_init(void)
  8469. +{
  8470. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  8471. + return platform_driver_register(&ar71xx_spi_drv);
  8472. +}
  8473. +module_init(ar71xx_spi_init);
  8474. +
  8475. +static void __exit ar71xx_spi_exit(void)
  8476. +{
  8477. + platform_driver_unregister(&ar71xx_spi_drv);
  8478. +}
  8479. +module_exit(ar71xx_spi_exit);
  8480. +
  8481. +MODULE_ALIAS("platform:" DRV_NAME);
  8482. +MODULE_DESCRIPTION(DRV_DESC);
  8483. +MODULE_VERSION(DRV_VERSION);
  8484. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  8485. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  8486. +MODULE_LICENSE("GPL v2");
  8487. diff -Nur linux-2.6.29.1.orig/drivers/usb/host/Kconfig linux-2.6.29.1/drivers/usb/host/Kconfig
  8488. --- linux-2.6.29.1.orig/drivers/usb/host/Kconfig 2009-04-02 22:55:27.000000000 +0200
  8489. +++ linux-2.6.29.1/drivers/usb/host/Kconfig 2009-04-13 14:27:34.855087329 +0200
  8490. @@ -81,6 +81,12 @@
  8491. depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX)
  8492. default y
  8493. +config USB_EHCI_AR71XX
  8494. + bool "USB EHCI support for AR71xx"
  8495. + depends on USB_EHCI_HCD && ATHEROS_AR71XX
  8496. + help
  8497. + Support for Atheros AR71xx built-in EHCI controller
  8498. +
  8499. config USB_EHCI_FSL
  8500. bool "Support for Freescale on-chip EHCI USB controller"
  8501. depends on USB_EHCI_HCD && FSL_SOC
  8502. @@ -154,6 +160,12 @@
  8503. To compile this driver as a module, choose M here: the
  8504. module will be called ohci-hcd.
  8505. +config USB_OHCI_AR71XX
  8506. + bool "USB OHCI support for Atheros AR71xx"
  8507. + depends on USB_OHCI_HCD && ATHEROS_AR71XX
  8508. + help
  8509. + Support for Atheros AR71xx built-in OHCI controller
  8510. +
  8511. config USB_OHCI_HCD_PPC_SOC
  8512. bool "OHCI support for on-chip PPC USB controller"
  8513. depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
  8514. diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.29.1/drivers/usb/host/ehci-ar71xx.c
  8515. --- linux-2.6.29.1.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  8516. +++ linux-2.6.29.1/drivers/usb/host/ehci-ar71xx.c 2009-04-13 14:27:34.859087838 +0200
  8517. @@ -0,0 +1,235 @@
  8518. +/*
  8519. + * Bus Glue for Atheros AR71xx built-in EHCI controller.
  8520. + *
  8521. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8522. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8523. + *
  8524. + * Parts of this file are based on Atheros' 2.6.15 BSP
  8525. + * Copyright (C) 2007 Atheros Communications, Inc.
  8526. + *
  8527. + * This program is free software; you can redistribute it and/or modify it
  8528. + * under the terms of the GNU General Public License version 2 as published
  8529. + * by the Free Software Foundation.
  8530. + */
  8531. +
  8532. +#include <linux/platform_device.h>
  8533. +#include <linux/delay.h>
  8534. +
  8535. +#include <asm/mach-ar71xx/platform.h>
  8536. +
  8537. +extern int usb_disabled(void);
  8538. +
  8539. +static int ehci_ar71xx_init(struct usb_hcd *hcd)
  8540. +{
  8541. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  8542. + int ret;
  8543. +
  8544. + ehci->caps = hcd->regs;
  8545. + ehci->regs = hcd->regs +
  8546. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  8547. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  8548. +
  8549. + ehci->sbrn = 0x20;
  8550. +
  8551. + ehci_reset(ehci);
  8552. +
  8553. + ret = ehci_init(hcd);
  8554. + if (ret)
  8555. + return ret;
  8556. +
  8557. + ehci_port_power(ehci, 0);
  8558. +
  8559. + return 0;
  8560. +}
  8561. +
  8562. +static int ehci_ar91xx_init(struct usb_hcd *hcd)
  8563. +{
  8564. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  8565. + int ret;
  8566. +
  8567. + ehci->caps = hcd->regs + 0x100;
  8568. + ehci->regs = hcd->regs + 0x100 +
  8569. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  8570. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  8571. +
  8572. + hcd->has_tt = 1;
  8573. + ehci->sbrn = 0x20;
  8574. +
  8575. + ehci_reset(ehci);
  8576. +
  8577. + ret = ehci_init(hcd);
  8578. + if (ret)
  8579. + return ret;
  8580. +
  8581. + ehci_port_power(ehci, 0);
  8582. +
  8583. + return 0;
  8584. +}
  8585. +
  8586. +static int ehci_ar71xx_probe(const struct hc_driver *driver,
  8587. + struct usb_hcd **hcd_out,
  8588. + struct platform_device *pdev)
  8589. +{
  8590. + struct usb_hcd *hcd;
  8591. + struct resource *res;
  8592. + int irq;
  8593. + int ret;
  8594. +
  8595. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  8596. + if (!res) {
  8597. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  8598. + pdev->dev.bus_id);
  8599. + return -ENODEV;
  8600. + }
  8601. + irq = res->start;
  8602. +
  8603. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  8604. + if (!res) {
  8605. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  8606. + pdev->dev.bus_id);
  8607. + return -ENODEV;
  8608. + }
  8609. +
  8610. + hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
  8611. + if (!hcd)
  8612. + return -ENOMEM;
  8613. +
  8614. + hcd->rsrc_start = res->start;
  8615. + hcd->rsrc_len = res->end - res->start + 1;
  8616. +
  8617. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  8618. + dev_dbg(&pdev->dev, "controller already in use\n");
  8619. + ret = -EBUSY;
  8620. + goto err_put_hcd;
  8621. + }
  8622. +
  8623. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  8624. + if (!hcd->regs) {
  8625. + dev_dbg(&pdev->dev, "error mapping memory\n");
  8626. + ret = -EFAULT;
  8627. + goto err_release_region;
  8628. + }
  8629. +
  8630. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  8631. + if (ret)
  8632. + goto err_iounmap;
  8633. +
  8634. + return 0;
  8635. +
  8636. + err_iounmap:
  8637. + iounmap(hcd->regs);
  8638. +
  8639. + err_release_region:
  8640. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  8641. + err_put_hcd:
  8642. + usb_put_hcd(hcd);
  8643. + return ret;
  8644. +}
  8645. +
  8646. +static void ehci_ar71xx_remove(struct usb_hcd *hcd,
  8647. + struct platform_device *pdev)
  8648. +{
  8649. + usb_remove_hcd(hcd);
  8650. + iounmap(hcd->regs);
  8651. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  8652. + usb_put_hcd(hcd);
  8653. +}
  8654. +
  8655. +static const struct hc_driver ehci_ar71xx_hc_driver = {
  8656. + .description = hcd_name,
  8657. + .product_desc = "Atheros AR71xx built-in EHCI controller",
  8658. + .hcd_priv_size = sizeof(struct ehci_hcd),
  8659. +
  8660. + .irq = ehci_irq,
  8661. + .flags = HCD_MEMORY | HCD_USB2,
  8662. +
  8663. + .reset = ehci_ar71xx_init,
  8664. + .start = ehci_run,
  8665. + .stop = ehci_stop,
  8666. + .shutdown = ehci_shutdown,
  8667. +
  8668. + .urb_enqueue = ehci_urb_enqueue,
  8669. + .urb_dequeue = ehci_urb_dequeue,
  8670. + .endpoint_disable = ehci_endpoint_disable,
  8671. +
  8672. + .get_frame_number = ehci_get_frame,
  8673. +
  8674. + .hub_status_data = ehci_hub_status_data,
  8675. + .hub_control = ehci_hub_control,
  8676. +#ifdef CONFIG_PM
  8677. + .hub_suspend = ehci_hub_suspend,
  8678. + .hub_resume = ehci_hub_resume,
  8679. +#endif
  8680. + .relinquish_port = ehci_relinquish_port,
  8681. + .port_handed_over = ehci_port_handed_over,
  8682. +};
  8683. +
  8684. +static const struct hc_driver ehci_ar91xx_hc_driver = {
  8685. + .description = hcd_name,
  8686. + .product_desc = "Atheros AR91xx built-in EHCI controller",
  8687. + .hcd_priv_size = sizeof(struct ehci_hcd),
  8688. + .irq = ehci_irq,
  8689. + .flags = HCD_MEMORY | HCD_USB2,
  8690. +
  8691. + .reset = ehci_ar91xx_init,
  8692. + .start = ehci_run,
  8693. + .stop = ehci_stop,
  8694. + .shutdown = ehci_shutdown,
  8695. +
  8696. + .urb_enqueue = ehci_urb_enqueue,
  8697. + .urb_dequeue = ehci_urb_dequeue,
  8698. + .endpoint_disable = ehci_endpoint_disable,
  8699. +
  8700. + .get_frame_number = ehci_get_frame,
  8701. +
  8702. + .hub_status_data = ehci_hub_status_data,
  8703. + .hub_control = ehci_hub_control,
  8704. +#ifdef CONFIG_PM
  8705. + .hub_suspend = ehci_hub_suspend,
  8706. + .hub_resume = ehci_hub_resume,
  8707. +#endif
  8708. + .relinquish_port = ehci_relinquish_port,
  8709. + .port_handed_over = ehci_port_handed_over,
  8710. +};
  8711. +
  8712. +static int ehci_ar71xx_driver_probe(struct platform_device *pdev)
  8713. +{
  8714. + struct ar71xx_ehci_platform_data *pdata;
  8715. + struct usb_hcd *hcd = NULL;
  8716. + int ret;
  8717. +
  8718. + if (usb_disabled())
  8719. + return -ENODEV;
  8720. +
  8721. + pdata = pdev->dev.platform_data;
  8722. + if (!pdata) {
  8723. + dev_err(&pdev->dev, "no platform data specified for %s\n",
  8724. + pdev->dev.bus_id);
  8725. + return -ENODEV;
  8726. + }
  8727. +
  8728. + if (pdata->is_ar91xx)
  8729. + ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev);
  8730. + else
  8731. + ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev);
  8732. +
  8733. + return ret;
  8734. +}
  8735. +
  8736. +static int ehci_ar71xx_driver_remove(struct platform_device *pdev)
  8737. +{
  8738. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  8739. +
  8740. + ehci_ar71xx_remove(hcd, pdev);
  8741. + return 0;
  8742. +}
  8743. +
  8744. +MODULE_ALIAS("platform:ar71xx-ehci");
  8745. +
  8746. +static struct platform_driver ehci_ar71xx_driver = {
  8747. + .probe = ehci_ar71xx_driver_probe,
  8748. + .remove = ehci_ar71xx_driver_remove,
  8749. + .driver = {
  8750. + .name = "ar71xx-ehci",
  8751. + }
  8752. +};
  8753. diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ehci-hcd.c linux-2.6.29.1/drivers/usb/host/ehci-hcd.c
  8754. --- linux-2.6.29.1.orig/drivers/usb/host/ehci-hcd.c 2009-04-02 22:55:27.000000000 +0200
  8755. +++ linux-2.6.29.1/drivers/usb/host/ehci-hcd.c 2009-04-13 14:27:34.859087838 +0200
  8756. @@ -1036,6 +1036,11 @@
  8757. #define PLATFORM_DRIVER ixp4xx_ehci_driver
  8758. #endif
  8759. +#ifdef CONFIG_USB_EHCI_AR71XX
  8760. +#include "ehci-ar71xx.c"
  8761. +#define PLATFORM_DRIVER ehci_ar71xx_driver
  8762. +#endif
  8763. +
  8764. #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
  8765. !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
  8766. #error "missing bus glue for ehci-hcd"
  8767. diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.29.1/drivers/usb/host/ohci-ar71xx.c
  8768. --- linux-2.6.29.1.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  8769. +++ linux-2.6.29.1/drivers/usb/host/ohci-ar71xx.c 2009-04-13 14:27:34.887088611 +0200
  8770. @@ -0,0 +1,165 @@
  8771. +/*
  8772. + * OHCI HCD (Host Controller Driver) for USB.
  8773. + *
  8774. + * Bus Glue for Atheros AR71xx built-in OHCI controller.
  8775. + *
  8776. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8777. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8778. + *
  8779. + * Parts of this file are based on Atheros' 2.6.15 BSP
  8780. + * Copyright (C) 2007 Atheros Communications, Inc.
  8781. + *
  8782. + * This program is free software; you can redistribute it and/or modify it
  8783. + * under the terms of the GNU General Public License version 2 as published
  8784. + * by the Free Software Foundation.
  8785. + */
  8786. +
  8787. +#include <linux/platform_device.h>
  8788. +#include <linux/delay.h>
  8789. +
  8790. +extern int usb_disabled(void);
  8791. +
  8792. +static int usb_hcd_ar71xx_probe(const struct hc_driver *driver,
  8793. + struct platform_device *pdev)
  8794. +{
  8795. + struct usb_hcd *hcd;
  8796. + struct resource *res;
  8797. + int irq;
  8798. + int ret;
  8799. +
  8800. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  8801. + if (!res) {
  8802. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  8803. + pdev->dev.bus_id);
  8804. + return -ENODEV;
  8805. + }
  8806. + irq = res->start;
  8807. +
  8808. + hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
  8809. + if (!hcd)
  8810. + return -ENOMEM;
  8811. +
  8812. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  8813. + if (!res) {
  8814. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  8815. + pdev->dev.bus_id);
  8816. + ret = -ENODEV;
  8817. + goto err_put_hcd;
  8818. + }
  8819. + hcd->rsrc_start = res->start;
  8820. + hcd->rsrc_len = res->end - res->start + 1;
  8821. +
  8822. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  8823. + dev_dbg(&pdev->dev, "controller already in use\n");
  8824. + ret = -EBUSY;
  8825. + goto err_put_hcd;
  8826. + }
  8827. +
  8828. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  8829. + if (!hcd->regs) {
  8830. + dev_dbg(&pdev->dev, "error mapping memory\n");
  8831. + ret = -EFAULT;
  8832. + goto err_release_region;
  8833. + }
  8834. +
  8835. + ohci_hcd_init(hcd_to_ohci(hcd));
  8836. +
  8837. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  8838. + if (ret)
  8839. + goto err_stop_hcd;
  8840. +
  8841. + return 0;
  8842. +
  8843. + err_stop_hcd:
  8844. + iounmap(hcd->regs);
  8845. + err_release_region:
  8846. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  8847. + err_put_hcd:
  8848. + usb_put_hcd(hcd);
  8849. + return ret;
  8850. +}
  8851. +
  8852. +void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  8853. +{
  8854. + usb_remove_hcd(hcd);
  8855. + iounmap(hcd->regs);
  8856. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  8857. + usb_put_hcd(hcd);
  8858. +}
  8859. +
  8860. +static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd)
  8861. +{
  8862. + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  8863. + int ret;
  8864. +
  8865. + ret = ohci_init(ohci);
  8866. + if (ret < 0)
  8867. + return ret;
  8868. +
  8869. + ret = ohci_run(ohci);
  8870. + if (ret < 0)
  8871. + goto err;
  8872. +
  8873. + return 0;
  8874. +
  8875. + err:
  8876. + ohci_stop(hcd);
  8877. + return ret;
  8878. +}
  8879. +
  8880. +static const struct hc_driver ohci_ar71xx_hc_driver = {
  8881. + .description = hcd_name,
  8882. + .product_desc = "Atheros AR71xx built-in OHCI controller",
  8883. + .hcd_priv_size = sizeof(struct ohci_hcd),
  8884. +
  8885. + .irq = ohci_irq,
  8886. + .flags = HCD_USB11 | HCD_MEMORY,
  8887. +
  8888. + .start = ohci_ar71xx_start,
  8889. + .stop = ohci_stop,
  8890. + .shutdown = ohci_shutdown,
  8891. +
  8892. + .urb_enqueue = ohci_urb_enqueue,
  8893. + .urb_dequeue = ohci_urb_dequeue,
  8894. + .endpoint_disable = ohci_endpoint_disable,
  8895. +
  8896. + /*
  8897. + * scheduling support
  8898. + */
  8899. + .get_frame_number = ohci_get_frame,
  8900. +
  8901. + /*
  8902. + * root hub support
  8903. + */
  8904. + .hub_status_data = ohci_hub_status_data,
  8905. + .hub_control = ohci_hub_control,
  8906. + .start_port_reset = ohci_start_port_reset,
  8907. +};
  8908. +
  8909. +static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev)
  8910. +{
  8911. + if (usb_disabled())
  8912. + return -ENODEV;
  8913. +
  8914. + return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev);
  8915. +}
  8916. +
  8917. +static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev)
  8918. +{
  8919. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  8920. +
  8921. + usb_hcd_ar71xx_remove(hcd, pdev);
  8922. + return 0;
  8923. +}
  8924. +
  8925. +MODULE_ALIAS("platform:ar71xx-ohci");
  8926. +
  8927. +static struct platform_driver ohci_hcd_ar71xx_driver = {
  8928. + .probe = ohci_hcd_ar71xx_drv_probe,
  8929. + .remove = ohci_hcd_ar71xx_drv_remove,
  8930. + .shutdown = usb_hcd_platform_shutdown,
  8931. + .driver = {
  8932. + .name = "ar71xx-ohci",
  8933. + .owner = THIS_MODULE,
  8934. + },
  8935. +};
  8936. diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ohci-hcd.c linux-2.6.29.1/drivers/usb/host/ohci-hcd.c
  8937. --- linux-2.6.29.1.orig/drivers/usb/host/ohci-hcd.c 2009-04-02 22:55:27.000000000 +0200
  8938. +++ linux-2.6.29.1/drivers/usb/host/ohci-hcd.c 2009-04-13 14:27:34.887088611 +0200
  8939. @@ -1080,6 +1080,11 @@
  8940. #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver
  8941. #endif
  8942. +#ifdef CONFIG_USB_OHCI_AR71XX
  8943. +#include "ohci-ar71xx.c"
  8944. +#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
  8945. +#endif
  8946. +
  8947. #if !defined(PCI_DRIVER) && \
  8948. !defined(PLATFORM_DRIVER) && \
  8949. !defined(OF_PLATFORM_DRIVER) && \
  8950. diff -Nur linux-2.6.29.1.orig/drivers/watchdog/Kconfig linux-2.6.29.1/drivers/watchdog/Kconfig
  8951. --- linux-2.6.29.1.orig/drivers/watchdog/Kconfig 2009-04-02 22:55:27.000000000 +0200
  8952. +++ linux-2.6.29.1/drivers/watchdog/Kconfig 2009-04-13 14:27:34.891089680 +0200
  8953. @@ -766,6 +766,13 @@
  8954. help
  8955. Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
  8956. +config AR71XX_WDT
  8957. + tristate "Atheros AR71xx Watchdog Timer"
  8958. + depends on ATHEROS_AR71XX
  8959. + help
  8960. + Hardware driver for the built-in watchdog timer on the Atheros
  8961. + AR71xx SoCs.
  8962. +
  8963. # PARISC Architecture
  8964. # POWERPC Architecture
  8965. diff -Nur linux-2.6.29.1.orig/drivers/watchdog/Makefile linux-2.6.29.1/drivers/watchdog/Makefile
  8966. --- linux-2.6.29.1.orig/drivers/watchdog/Makefile 2009-04-02 22:55:27.000000000 +0200
  8967. +++ linux-2.6.29.1/drivers/watchdog/Makefile 2009-04-13 14:27:34.891089680 +0200
  8968. @@ -107,6 +107,7 @@
  8969. obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
  8970. obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
  8971. obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
  8972. +obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
  8973. # PARISC Architecture
  8974. diff -Nur linux-2.6.29.1.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.29.1/drivers/watchdog/ar71xx_wdt.c
  8975. --- linux-2.6.29.1.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100
  8976. +++ linux-2.6.29.1/drivers/watchdog/ar71xx_wdt.c 2009-04-13 14:27:34.915091622 +0200
  8977. @@ -0,0 +1,270 @@
  8978. +/*
  8979. + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer.
  8980. + *
  8981. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8982. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8983. + *
  8984. + * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
  8985. + * Author: Deepak Saxena <dsaxena@plexity.net>
  8986. + * Copyright 2004 (c) MontaVista, Software, Inc.
  8987. + *
  8988. + * which again was based on sa1100 driver,
  8989. + * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
  8990. + *
  8991. + * This program is free software; you can redistribute it and/or modify it
  8992. + * under the terms of the GNU General Public License version 2 as published
  8993. + * by the Free Software Foundation.
  8994. + *
  8995. + */
  8996. +
  8997. +#include <linux/bitops.h>
  8998. +#include <linux/errno.h>
  8999. +#include <linux/fs.h>
  9000. +#include <linux/init.h>
  9001. +#include <linux/kernel.h>
  9002. +#include <linux/miscdevice.h>
  9003. +#include <linux/module.h>
  9004. +#include <linux/moduleparam.h>
  9005. +#include <linux/platform_device.h>
  9006. +#include <linux/types.h>
  9007. +#include <linux/watchdog.h>
  9008. +
  9009. +#include <asm/mach-ar71xx/ar71xx.h>
  9010. +
  9011. +#define DRV_NAME "ar71xx-wdt"
  9012. +#define DRV_DESC "Atheros AR71xx hardware watchdog driver"
  9013. +#define DRV_VERSION "0.1.0"
  9014. +
  9015. +#define WDT_TIMEOUT 15 /* seconds */
  9016. +
  9017. +static int nowayout = WATCHDOG_NOWAYOUT;
  9018. +
  9019. +#ifdef CONFIG_WATCHDOG_NOWAYOUT
  9020. +module_param(nowayout, int, 0);
  9021. +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  9022. + "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  9023. +#endif
  9024. +
  9025. +static unsigned long wdt_flags;
  9026. +
  9027. +#define WDT_FLAGS_BUSY 0
  9028. +#define WDT_FLAGS_EXPECT_CLOSE 1
  9029. +
  9030. +static int wdt_timeout = WDT_TIMEOUT;
  9031. +static int boot_status;
  9032. +static int max_timeout;
  9033. +
  9034. +static void inline ar71xx_wdt_keepalive(void)
  9035. +{
  9036. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout);
  9037. +}
  9038. +
  9039. +static void inline ar71xx_wdt_enable(void)
  9040. +{
  9041. + printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n");
  9042. + ar71xx_wdt_keepalive();
  9043. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
  9044. +}
  9045. +
  9046. +static void inline ar71xx_wdt_disable(void)
  9047. +{
  9048. + printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n");
  9049. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
  9050. +}
  9051. +
  9052. +static int ar71xx_wdt_set_timeout(int val)
  9053. +{
  9054. + if (val < 1 || val > max_timeout)
  9055. + return -EINVAL;
  9056. +
  9057. + wdt_timeout = val;
  9058. + ar71xx_wdt_keepalive();
  9059. +
  9060. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout);
  9061. +
  9062. + return 0;
  9063. +}
  9064. +
  9065. +static int ar71xx_wdt_open(struct inode *inode, struct file *file)
  9066. +{
  9067. + if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
  9068. + return -EBUSY;
  9069. +
  9070. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  9071. +
  9072. + ar71xx_wdt_enable();
  9073. +
  9074. + return nonseekable_open(inode, file);
  9075. +}
  9076. +
  9077. +static int ar71xx_wdt_release(struct inode *inode, struct file *file)
  9078. +{
  9079. + if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) {
  9080. + ar71xx_wdt_disable();
  9081. + } else {
  9082. + printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, "
  9083. + "watchdog timer will not stop!\n");
  9084. + }
  9085. +
  9086. + clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
  9087. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  9088. +
  9089. + return 0;
  9090. +}
  9091. +
  9092. +static ssize_t ar71xx_wdt_write(struct file *file, const char *data,
  9093. + size_t len, loff_t *ppos)
  9094. +{
  9095. + if (len) {
  9096. + if (!nowayout) {
  9097. + size_t i;
  9098. +
  9099. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  9100. +
  9101. + for (i = 0; i != len; i++) {
  9102. + char c;
  9103. +
  9104. + if (get_user(c, data + i))
  9105. + return -EFAULT;
  9106. +
  9107. + if (c == 'V')
  9108. + set_bit(WDT_FLAGS_EXPECT_CLOSE,
  9109. + &wdt_flags);
  9110. + }
  9111. + }
  9112. +
  9113. + ar71xx_wdt_keepalive();
  9114. + }
  9115. +
  9116. + return len;
  9117. +}
  9118. +
  9119. +static struct watchdog_info ar71xx_wdt_info = {
  9120. + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
  9121. + WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
  9122. + .firmware_version = 0,
  9123. + .identity = "AR71XX watchdog",
  9124. +};
  9125. +
  9126. +static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file,
  9127. + unsigned int cmd, unsigned long arg)
  9128. +{
  9129. + int t;
  9130. + int ret;
  9131. +
  9132. + switch (cmd) {
  9133. + case WDIOC_GETSUPPORT:
  9134. + ret = copy_to_user((struct watchdog_info *)arg,
  9135. + &ar71xx_wdt_info,
  9136. + sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0;
  9137. + break;
  9138. +
  9139. + case WDIOC_GETSTATUS:
  9140. + ret = put_user(0, (int *)arg) ? -EFAULT : 0;
  9141. + break;
  9142. +
  9143. + case WDIOC_GETBOOTSTATUS:
  9144. + ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0;
  9145. + break;
  9146. +
  9147. + case WDIOC_KEEPALIVE:
  9148. + ar71xx_wdt_keepalive();
  9149. + ret = 0;
  9150. + break;
  9151. +
  9152. + case WDIOC_SETTIMEOUT:
  9153. + ret = get_user(t, (int *)arg) ? -EFAULT : 0;
  9154. + if (ret)
  9155. + break;
  9156. +
  9157. + ret = ar71xx_wdt_set_timeout(t);
  9158. + if (ret)
  9159. + break;
  9160. +
  9161. + /* fallthrough */
  9162. + case WDIOC_GETTIMEOUT:
  9163. + ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0;
  9164. + break;
  9165. +
  9166. + default:
  9167. + ret = -ENOTTY;
  9168. + break;
  9169. + }
  9170. +
  9171. + return ret;
  9172. +}
  9173. +
  9174. +static const struct file_operations ar71xx_wdt_fops = {
  9175. + .owner = THIS_MODULE,
  9176. + .write = ar71xx_wdt_write,
  9177. + .ioctl = ar71xx_wdt_ioctl,
  9178. + .open = ar71xx_wdt_open,
  9179. + .release = ar71xx_wdt_release,
  9180. +};
  9181. +
  9182. +static struct miscdevice ar71xx_wdt_miscdev = {
  9183. + .minor = WATCHDOG_MINOR,
  9184. + .name = "watchdog",
  9185. + .fops = &ar71xx_wdt_fops,
  9186. +};
  9187. +
  9188. +static int __devinit ar71xx_wdt_probe(struct platform_device *pdev)
  9189. +{
  9190. + int ret;
  9191. +
  9192. + max_timeout = (0xfffffffful / ar71xx_ahb_freq);
  9193. + wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
  9194. +
  9195. + boot_status =
  9196. + (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ?
  9197. + WDIOF_CARDRESET : 0;
  9198. +
  9199. + ret = misc_register(&ar71xx_wdt_miscdev);
  9200. + if (ret)
  9201. + goto err_out;
  9202. +
  9203. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  9204. +
  9205. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n",
  9206. + wdt_timeout, max_timeout);
  9207. +
  9208. + return 0;
  9209. +
  9210. +err_out:
  9211. + return ret;
  9212. +}
  9213. +
  9214. +static int __devexit ar71xx_wdt_remove(struct platform_device *pdev)
  9215. +{
  9216. + misc_deregister(&ar71xx_wdt_miscdev);
  9217. + return 0;
  9218. +}
  9219. +
  9220. +static struct platform_driver ar71xx_wdt_driver = {
  9221. + .probe = ar71xx_wdt_probe,
  9222. + .remove = __devexit_p(ar71xx_wdt_remove),
  9223. + .driver = {
  9224. + .name = DRV_NAME,
  9225. + .owner = THIS_MODULE,
  9226. + },
  9227. +};
  9228. +
  9229. +static int __init ar71xx_wdt_init(void)
  9230. +{
  9231. + return platform_driver_register(&ar71xx_wdt_driver);
  9232. +}
  9233. +module_init(ar71xx_wdt_init);
  9234. +
  9235. +static void __exit ar71xx_wdt_exit(void)
  9236. +{
  9237. + platform_driver_unregister(&ar71xx_wdt_driver);
  9238. +}
  9239. +module_exit(ar71xx_wdt_exit);
  9240. +
  9241. +MODULE_DESCRIPTION(DRV_DESC);
  9242. +MODULE_VERSION(DRV_VERSION);
  9243. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
  9244. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
  9245. +MODULE_LICENSE("GPL v2");
  9246. +MODULE_ALIAS("platform:" DRV_NAME);
  9247. +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  9248. diff -Nur linux-2.6.29.1.orig/include/asm-mips/mips_machine.h linux-2.6.29.1/include/asm-mips/mips_machine.h
  9249. --- linux-2.6.29.1.orig/include/asm-mips/mips_machine.h 1970-01-01 01:00:00.000000000 +0100
  9250. +++ linux-2.6.29.1/include/asm-mips/mips_machine.h 2009-04-13 14:27:34.915091622 +0200
  9251. @@ -0,0 +1,47 @@
  9252. +/*
  9253. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  9254. + *
  9255. + * This program is free software; you can redistribute it and/or modify it
  9256. + * under the terms of the GNU General Public License version 2 as published
  9257. + * by the Free Software Foundation.
  9258. + *
  9259. + */
  9260. +
  9261. +#ifndef __ASM_MIPS_MACHINE_H
  9262. +#define __ASM_MIPS_MACHINE_H
  9263. +
  9264. +#include <linux/init.h>
  9265. +#include <linux/list.h>
  9266. +
  9267. +#define MIPS_MACHINE_NAME_LEN 64
  9268. +
  9269. +struct mips_machine {
  9270. + unsigned long mach_type;
  9271. + void (*mach_setup)(void);
  9272. + unsigned char mach_name[MIPS_MACHINE_NAME_LEN];
  9273. + struct list_head list;
  9274. +};
  9275. +
  9276. +void mips_machine_register(struct mips_machine *) __init;
  9277. +void mips_machine_setup(unsigned long machtype) __init;
  9278. +
  9279. +extern unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN];
  9280. +
  9281. +#define MIPS_MACHINE(_type, _name, _setup) \
  9282. +static struct mips_machine machine_##_type __initdata = \
  9283. +{ \
  9284. + .mach_type = _type, \
  9285. + .mach_name = _name, \
  9286. + .mach_setup = _setup, \
  9287. +}; \
  9288. + \
  9289. +static int __init register_machine_##_type(void) \
  9290. +{ \
  9291. + mips_machine_register(&machine_##_type); \
  9292. + return 0; \
  9293. +} \
  9294. + \
  9295. +pure_initcall(register_machine_##_type)
  9296. +
  9297. +#endif /* __ASM_MIPS_MACHINE_H */
  9298. +
  9299. diff -Nur linux-2.6.29.1.orig/include/linux/ath9k_platform.h linux-2.6.29.1/include/linux/ath9k_platform.h
  9300. --- linux-2.6.29.1.orig/include/linux/ath9k_platform.h 1970-01-01 01:00:00.000000000 +0100
  9301. +++ linux-2.6.29.1/include/linux/ath9k_platform.h 2009-04-13 14:27:34.915091622 +0200
  9302. @@ -0,0 +1,20 @@
  9303. +/*
  9304. + * ath9k platform data defines
  9305. + *
  9306. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  9307. + *
  9308. + * This program is free software; you can redistribute it and/or modify it
  9309. + * under the terms of the GNU General Public License version 2 as published
  9310. + * by the Free Software Foundation.
  9311. + */
  9312. +
  9313. +#ifndef _LINUX_ATH9K_PLATFORM_H
  9314. +#define _LINUX_ATH9L_PLATFORM_H
  9315. +
  9316. +#define ATH9K_PLAT_EEP_MAX_WORDS 2048
  9317. +
  9318. +struct ath9k_platform_data {
  9319. + u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  9320. +};
  9321. +
  9322. +#endif /* _LINUX_ATH9K_PLATFORM_H */
  9323. diff -Nur linux-2.6.29.1.orig/include/linux/gpio_buttons.h linux-2.6.29.1/include/linux/gpio_buttons.h
  9324. --- linux-2.6.29.1.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100
  9325. +++ linux-2.6.29.1/include/linux/gpio_buttons.h 2009-04-13 14:27:34.919091574 +0200
  9326. @@ -0,0 +1,35 @@
  9327. +/*
  9328. + * Definitions for the GPIO buttons interface driver
  9329. + *
  9330. + * Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org>
  9331. + *
  9332. + * This file was based on: /include/linux/gpio_keys.h
  9333. + * The original gpio_keys.h seems not to have a license.
  9334. + *
  9335. + * This program is free software; you can redistribute it and/or modify
  9336. + * it under the terms of the GNU General Public License version 2 as
  9337. + * published by the Free Software Foundation.
  9338. + *
  9339. + */
  9340. +
  9341. +#ifndef _GPIO_BUTTONS_H_
  9342. +#define _GPIO_BUTTONS_H_
  9343. +
  9344. +struct gpio_button {
  9345. + int gpio; /* GPIO line number */
  9346. + int active_low;
  9347. + char *desc; /* button description */
  9348. + int type; /* input event type (EV_KEY, EV_SW) */
  9349. + int code; /* input event code (KEY_*, SW_*) */
  9350. + int count;
  9351. + int threshold; /* count threshold */
  9352. +};
  9353. +
  9354. +struct gpio_buttons_platform_data {
  9355. + struct gpio_button *buttons;
  9356. + int nbuttons; /* number of buttons */
  9357. + int poll_interval; /* polling interval */
  9358. +};
  9359. +
  9360. +#endif /* _GPIO_BUTTONS_H_ */
  9361. +
  9362. diff -Nur linux-2.6.29.1.orig/include/linux/phy.h linux-2.6.29.1/include/linux/phy.h
  9363. --- linux-2.6.29.1.orig/include/linux/phy.h 2009-04-02 22:55:27.000000000 +0200
  9364. +++ linux-2.6.29.1/include/linux/phy.h 2009-04-13 17:29:37.057990291 +0200
  9365. @@ -478,6 +478,7 @@
  9366. void phy_stop_machine(struct phy_device *phydev);
  9367. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  9368. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  9369. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  9370. int phy_mii_ioctl(struct phy_device *phydev,
  9371. struct mii_ioctl_data *mii_data, int cmd);
  9372. int phy_start_interrupts(struct phy_device *phydev);
  9373. diff -Nur linux-2.6.29.1.orig/include/linux/phy.h.orig linux-2.6.29.1/include/linux/phy.h.orig
  9374. --- linux-2.6.29.1.orig/include/linux/phy.h.orig 1970-01-01 01:00:00.000000000 +0100
  9375. +++ linux-2.6.29.1/include/linux/phy.h.orig 2009-04-02 22:55:27.000000000 +0200
  9376. @@ -0,0 +1,500 @@
  9377. +/*
  9378. + * include/linux/phy.h
  9379. + *
  9380. + * Framework and drivers for configuring and reading different PHYs
  9381. + * Based on code in sungem_phy.c and gianfar_phy.c
  9382. + *
  9383. + * Author: Andy Fleming
  9384. + *
  9385. + * Copyright (c) 2004 Freescale Semiconductor, Inc.
  9386. + *
  9387. + * This program is free software; you can redistribute it and/or modify it
  9388. + * under the terms of the GNU General Public License as published by the
  9389. + * Free Software Foundation; either version 2 of the License, or (at your
  9390. + * option) any later version.
  9391. + *
  9392. + */
  9393. +
  9394. +#ifndef __PHY_H
  9395. +#define __PHY_H
  9396. +
  9397. +#include <linux/spinlock.h>
  9398. +#include <linux/device.h>
  9399. +#include <linux/ethtool.h>
  9400. +#include <linux/mii.h>
  9401. +#include <linux/timer.h>
  9402. +#include <linux/workqueue.h>
  9403. +
  9404. +#include <asm/atomic.h>
  9405. +
  9406. +#define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
  9407. + SUPPORTED_10baseT_Full | \
  9408. + SUPPORTED_100baseT_Half | \
  9409. + SUPPORTED_100baseT_Full | \
  9410. + SUPPORTED_Autoneg | \
  9411. + SUPPORTED_TP | \
  9412. + SUPPORTED_MII)
  9413. +
  9414. +#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
  9415. + SUPPORTED_1000baseT_Half | \
  9416. + SUPPORTED_1000baseT_Full)
  9417. +
  9418. +/*
  9419. + * Set phydev->irq to PHY_POLL if interrupts are not supported,
  9420. + * or not desired for this PHY. Set to PHY_IGNORE_INTERRUPT if
  9421. + * the attached driver handles the interrupt
  9422. + */
  9423. +#define PHY_POLL -1
  9424. +#define PHY_IGNORE_INTERRUPT -2
  9425. +
  9426. +#define PHY_HAS_INTERRUPT 0x00000001
  9427. +#define PHY_HAS_MAGICANEG 0x00000002
  9428. +
  9429. +/* Interface Mode definitions */
  9430. +typedef enum {
  9431. + PHY_INTERFACE_MODE_MII,
  9432. + PHY_INTERFACE_MODE_GMII,
  9433. + PHY_INTERFACE_MODE_SGMII,
  9434. + PHY_INTERFACE_MODE_TBI,
  9435. + PHY_INTERFACE_MODE_RMII,
  9436. + PHY_INTERFACE_MODE_RGMII,
  9437. + PHY_INTERFACE_MODE_RGMII_ID,
  9438. + PHY_INTERFACE_MODE_RGMII_RXID,
  9439. + PHY_INTERFACE_MODE_RGMII_TXID,
  9440. + PHY_INTERFACE_MODE_RTBI
  9441. +} phy_interface_t;
  9442. +
  9443. +
  9444. +#define PHY_INIT_TIMEOUT 100000
  9445. +#define PHY_STATE_TIME 1
  9446. +#define PHY_FORCE_TIMEOUT 10
  9447. +#define PHY_AN_TIMEOUT 10
  9448. +
  9449. +#define PHY_MAX_ADDR 32
  9450. +
  9451. +/* Used when trying to connect to a specific phy (mii bus id:phy device id) */
  9452. +#define PHY_ID_FMT "%s:%02x"
  9453. +
  9454. +/*
  9455. + * Need to be a little smaller than phydev->dev.bus_id to leave room
  9456. + * for the ":%02x"
  9457. + */
  9458. +#define MII_BUS_ID_SIZE (BUS_ID_SIZE - 3)
  9459. +
  9460. +/*
  9461. + * The Bus class for PHYs. Devices which provide access to
  9462. + * PHYs should register using this structure
  9463. + */
  9464. +struct mii_bus {
  9465. + const char *name;
  9466. + char id[MII_BUS_ID_SIZE];
  9467. + void *priv;
  9468. + int (*read)(struct mii_bus *bus, int phy_id, int regnum);
  9469. + int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
  9470. + int (*reset)(struct mii_bus *bus);
  9471. +
  9472. + /*
  9473. + * A lock to ensure that only one thing can read/write
  9474. + * the MDIO bus at a time
  9475. + */
  9476. + struct mutex mdio_lock;
  9477. +
  9478. + struct device *parent;
  9479. + enum {
  9480. + MDIOBUS_ALLOCATED = 1,
  9481. + MDIOBUS_REGISTERED,
  9482. + MDIOBUS_UNREGISTERED,
  9483. + MDIOBUS_RELEASED,
  9484. + } state;
  9485. + struct device dev;
  9486. +
  9487. + /* list of all PHYs on bus */
  9488. + struct phy_device *phy_map[PHY_MAX_ADDR];
  9489. +
  9490. + /* Phy addresses to be ignored when probing */
  9491. + u32 phy_mask;
  9492. +
  9493. + /*
  9494. + * Pointer to an array of interrupts, each PHY's
  9495. + * interrupt at the index matching its address
  9496. + */
  9497. + int *irq;
  9498. +};
  9499. +#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
  9500. +
  9501. +struct mii_bus *mdiobus_alloc(void);
  9502. +int mdiobus_register(struct mii_bus *bus);
  9503. +void mdiobus_unregister(struct mii_bus *bus);
  9504. +void mdiobus_free(struct mii_bus *bus);
  9505. +struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
  9506. +int mdiobus_read(struct mii_bus *bus, int addr, u16 regnum);
  9507. +int mdiobus_write(struct mii_bus *bus, int addr, u16 regnum, u16 val);
  9508. +
  9509. +
  9510. +#define PHY_INTERRUPT_DISABLED 0x0
  9511. +#define PHY_INTERRUPT_ENABLED 0x80000000
  9512. +
  9513. +/* PHY state machine states:
  9514. + *
  9515. + * DOWN: PHY device and driver are not ready for anything. probe
  9516. + * should be called if and only if the PHY is in this state,
  9517. + * given that the PHY device exists.
  9518. + * - PHY driver probe function will, depending on the PHY, set
  9519. + * the state to STARTING or READY
  9520. + *
  9521. + * STARTING: PHY device is coming up, and the ethernet driver is
  9522. + * not ready. PHY drivers may set this in the probe function.
  9523. + * If they do, they are responsible for making sure the state is
  9524. + * eventually set to indicate whether the PHY is UP or READY,
  9525. + * depending on the state when the PHY is done starting up.
  9526. + * - PHY driver will set the state to READY
  9527. + * - start will set the state to PENDING
  9528. + *
  9529. + * READY: PHY is ready to send and receive packets, but the
  9530. + * controller is not. By default, PHYs which do not implement
  9531. + * probe will be set to this state by phy_probe(). If the PHY
  9532. + * driver knows the PHY is ready, and the PHY state is STARTING,
  9533. + * then it sets this STATE.
  9534. + * - start will set the state to UP
  9535. + *
  9536. + * PENDING: PHY device is coming up, but the ethernet driver is
  9537. + * ready. phy_start will set this state if the PHY state is
  9538. + * STARTING.
  9539. + * - PHY driver will set the state to UP when the PHY is ready
  9540. + *
  9541. + * UP: The PHY and attached device are ready to do work.
  9542. + * Interrupts should be started here.
  9543. + * - timer moves to AN
  9544. + *
  9545. + * AN: The PHY is currently negotiating the link state. Link is
  9546. + * therefore down for now. phy_timer will set this state when it
  9547. + * detects the state is UP. config_aneg will set this state
  9548. + * whenever called with phydev->autoneg set to AUTONEG_ENABLE.
  9549. + * - If autonegotiation finishes, but there's no link, it sets
  9550. + * the state to NOLINK.
  9551. + * - If aneg finishes with link, it sets the state to RUNNING,
  9552. + * and calls adjust_link
  9553. + * - If autonegotiation did not finish after an arbitrary amount
  9554. + * of time, autonegotiation should be tried again if the PHY
  9555. + * supports "magic" autonegotiation (back to AN)
  9556. + * - If it didn't finish, and no magic_aneg, move to FORCING.
  9557. + *
  9558. + * NOLINK: PHY is up, but not currently plugged in.
  9559. + * - If the timer notes that the link comes back, we move to RUNNING
  9560. + * - config_aneg moves to AN
  9561. + * - phy_stop moves to HALTED
  9562. + *
  9563. + * FORCING: PHY is being configured with forced settings
  9564. + * - if link is up, move to RUNNING
  9565. + * - If link is down, we drop to the next highest setting, and
  9566. + * retry (FORCING) after a timeout
  9567. + * - phy_stop moves to HALTED
  9568. + *
  9569. + * RUNNING: PHY is currently up, running, and possibly sending
  9570. + * and/or receiving packets
  9571. + * - timer will set CHANGELINK if we're polling (this ensures the
  9572. + * link state is polled every other cycle of this state machine,
  9573. + * which makes it every other second)
  9574. + * - irq will set CHANGELINK
  9575. + * - config_aneg will set AN
  9576. + * - phy_stop moves to HALTED
  9577. + *
  9578. + * CHANGELINK: PHY experienced a change in link state
  9579. + * - timer moves to RUNNING if link
  9580. + * - timer moves to NOLINK if the link is down
  9581. + * - phy_stop moves to HALTED
  9582. + *
  9583. + * HALTED: PHY is up, but no polling or interrupts are done. Or
  9584. + * PHY is in an error state.
  9585. + *
  9586. + * - phy_start moves to RESUMING
  9587. + *
  9588. + * RESUMING: PHY was halted, but now wants to run again.
  9589. + * - If we are forcing, or aneg is done, timer moves to RUNNING
  9590. + * - If aneg is not done, timer moves to AN
  9591. + * - phy_stop moves to HALTED
  9592. + */
  9593. +enum phy_state {
  9594. + PHY_DOWN=0,
  9595. + PHY_STARTING,
  9596. + PHY_READY,
  9597. + PHY_PENDING,
  9598. + PHY_UP,
  9599. + PHY_AN,
  9600. + PHY_RUNNING,
  9601. + PHY_NOLINK,
  9602. + PHY_FORCING,
  9603. + PHY_CHANGELINK,
  9604. + PHY_HALTED,
  9605. + PHY_RESUMING
  9606. +};
  9607. +
  9608. +/* phy_device: An instance of a PHY
  9609. + *
  9610. + * drv: Pointer to the driver for this PHY instance
  9611. + * bus: Pointer to the bus this PHY is on
  9612. + * dev: driver model device structure for this PHY
  9613. + * phy_id: UID for this device found during discovery
  9614. + * state: state of the PHY for management purposes
  9615. + * dev_flags: Device-specific flags used by the PHY driver.
  9616. + * addr: Bus address of PHY
  9617. + * link_timeout: The number of timer firings to wait before the
  9618. + * giving up on the current attempt at acquiring a link
  9619. + * irq: IRQ number of the PHY's interrupt (-1 if none)
  9620. + * phy_timer: The timer for handling the state machine
  9621. + * phy_queue: A work_queue for the interrupt
  9622. + * attached_dev: The attached enet driver's device instance ptr
  9623. + * adjust_link: Callback for the enet controller to respond to
  9624. + * changes in the link state.
  9625. + * adjust_state: Callback for the enet driver to respond to
  9626. + * changes in the state machine.
  9627. + *
  9628. + * speed, duplex, pause, supported, advertising, and
  9629. + * autoneg are used like in mii_if_info
  9630. + *
  9631. + * interrupts currently only supports enabled or disabled,
  9632. + * but could be changed in the future to support enabling
  9633. + * and disabling specific interrupts
  9634. + *
  9635. + * Contains some infrastructure for polling and interrupt
  9636. + * handling, as well as handling shifts in PHY hardware state
  9637. + */
  9638. +struct phy_device {
  9639. + /* Information about the PHY type */
  9640. + /* And management functions */
  9641. + struct phy_driver *drv;
  9642. +
  9643. + struct mii_bus *bus;
  9644. +
  9645. + struct device dev;
  9646. +
  9647. + u32 phy_id;
  9648. +
  9649. + enum phy_state state;
  9650. +
  9651. + u32 dev_flags;
  9652. +
  9653. + phy_interface_t interface;
  9654. +
  9655. + /* Bus address of the PHY (0-32) */
  9656. + int addr;
  9657. +
  9658. + /*
  9659. + * forced speed & duplex (no autoneg)
  9660. + * partner speed & duplex & pause (autoneg)
  9661. + */
  9662. + int speed;
  9663. + int duplex;
  9664. + int pause;
  9665. + int asym_pause;
  9666. +
  9667. + /* The most recently read link state */
  9668. + int link;
  9669. +
  9670. + /* Enabled Interrupts */
  9671. + u32 interrupts;
  9672. +
  9673. + /* Union of PHY and Attached devices' supported modes */
  9674. + /* See mii.h for more info */
  9675. + u32 supported;
  9676. + u32 advertising;
  9677. +
  9678. + int autoneg;
  9679. +
  9680. + int link_timeout;
  9681. +
  9682. + /*
  9683. + * Interrupt number for this PHY
  9684. + * -1 means no interrupt
  9685. + */
  9686. + int irq;
  9687. +
  9688. + /* private data pointer */
  9689. + /* For use by PHYs to maintain extra state */
  9690. + void *priv;
  9691. +
  9692. + /* Interrupt and Polling infrastructure */
  9693. + struct work_struct phy_queue;
  9694. + struct work_struct state_queue;
  9695. + struct timer_list phy_timer;
  9696. + atomic_t irq_disable;
  9697. +
  9698. + struct mutex lock;
  9699. +
  9700. + struct net_device *attached_dev;
  9701. +
  9702. + void (*adjust_link)(struct net_device *dev);
  9703. +
  9704. + void (*adjust_state)(struct net_device *dev);
  9705. +};
  9706. +#define to_phy_device(d) container_of(d, struct phy_device, dev)
  9707. +
  9708. +/* struct phy_driver: Driver structure for a particular PHY type
  9709. + *
  9710. + * phy_id: The result of reading the UID registers of this PHY
  9711. + * type, and ANDing them with the phy_id_mask. This driver
  9712. + * only works for PHYs with IDs which match this field
  9713. + * name: The friendly name of this PHY type
  9714. + * phy_id_mask: Defines the important bits of the phy_id
  9715. + * features: A list of features (speed, duplex, etc) supported
  9716. + * by this PHY
  9717. + * flags: A bitfield defining certain other features this PHY
  9718. + * supports (like interrupts)
  9719. + *
  9720. + * The drivers must implement config_aneg and read_status. All
  9721. + * other functions are optional. Note that none of these
  9722. + * functions should be called from interrupt time. The goal is
  9723. + * for the bus read/write functions to be able to block when the
  9724. + * bus transaction is happening, and be freed up by an interrupt
  9725. + * (The MPC85xx has this ability, though it is not currently
  9726. + * supported in the driver).
  9727. + */
  9728. +struct phy_driver {
  9729. + u32 phy_id;
  9730. + char *name;
  9731. + unsigned int phy_id_mask;
  9732. + u32 features;
  9733. + u32 flags;
  9734. +
  9735. + /*
  9736. + * Called to initialize the PHY,
  9737. + * including after a reset
  9738. + */
  9739. + int (*config_init)(struct phy_device *phydev);
  9740. +
  9741. + /*
  9742. + * Called during discovery. Used to set
  9743. + * up device-specific structures, if any
  9744. + */
  9745. + int (*probe)(struct phy_device *phydev);
  9746. +
  9747. + /* PHY Power Management */
  9748. + int (*suspend)(struct phy_device *phydev);
  9749. + int (*resume)(struct phy_device *phydev);
  9750. +
  9751. + /*
  9752. + * Configures the advertisement and resets
  9753. + * autonegotiation if phydev->autoneg is on,
  9754. + * forces the speed to the current settings in phydev
  9755. + * if phydev->autoneg is off
  9756. + */
  9757. + int (*config_aneg)(struct phy_device *phydev);
  9758. +
  9759. + /* Determines the negotiated speed and duplex */
  9760. + int (*read_status)(struct phy_device *phydev);
  9761. +
  9762. + /* Clears any pending interrupts */
  9763. + int (*ack_interrupt)(struct phy_device *phydev);
  9764. +
  9765. + /* Enables or disables interrupts */
  9766. + int (*config_intr)(struct phy_device *phydev);
  9767. +
  9768. + /* Clears up any memory if needed */
  9769. + void (*remove)(struct phy_device *phydev);
  9770. +
  9771. + struct device_driver driver;
  9772. +};
  9773. +#define to_phy_driver(d) container_of(d, struct phy_driver, driver)
  9774. +
  9775. +#define PHY_ANY_ID "MATCH ANY PHY"
  9776. +#define PHY_ANY_UID 0xffffffff
  9777. +
  9778. +/* A Structure for boards to register fixups with the PHY Lib */
  9779. +struct phy_fixup {
  9780. + struct list_head list;
  9781. + char bus_id[BUS_ID_SIZE];
  9782. + u32 phy_uid;
  9783. + u32 phy_uid_mask;
  9784. + int (*run)(struct phy_device *phydev);
  9785. +};
  9786. +
  9787. +/**
  9788. + * phy_read - Convenience function for reading a given PHY register
  9789. + * @phydev: the phy_device struct
  9790. + * @regnum: register number to read
  9791. + *
  9792. + * NOTE: MUST NOT be called from interrupt context,
  9793. + * because the bus read/write functions may wait for an interrupt
  9794. + * to conclude the operation.
  9795. + */
  9796. +static inline int phy_read(struct phy_device *phydev, u16 regnum)
  9797. +{
  9798. + return mdiobus_read(phydev->bus, phydev->addr, regnum);
  9799. +}
  9800. +
  9801. +/**
  9802. + * phy_write - Convenience function for writing a given PHY register
  9803. + * @phydev: the phy_device struct
  9804. + * @regnum: register number to write
  9805. + * @val: value to write to @regnum
  9806. + *
  9807. + * NOTE: MUST NOT be called from interrupt context,
  9808. + * because the bus read/write functions may wait for an interrupt
  9809. + * to conclude the operation.
  9810. + */
  9811. +static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
  9812. +{
  9813. + return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
  9814. +}
  9815. +
  9816. +int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
  9817. +struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
  9818. +int phy_clear_interrupt(struct phy_device *phydev);
  9819. +int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
  9820. +struct phy_device * phy_attach(struct net_device *dev,
  9821. + const char *bus_id, u32 flags, phy_interface_t interface);
  9822. +struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
  9823. + void (*handler)(struct net_device *), u32 flags,
  9824. + phy_interface_t interface);
  9825. +void phy_disconnect(struct phy_device *phydev);
  9826. +void phy_detach(struct phy_device *phydev);
  9827. +void phy_start(struct phy_device *phydev);
  9828. +void phy_stop(struct phy_device *phydev);
  9829. +int phy_start_aneg(struct phy_device *phydev);
  9830. +
  9831. +void phy_sanitize_settings(struct phy_device *phydev);
  9832. +int phy_stop_interrupts(struct phy_device *phydev);
  9833. +int phy_enable_interrupts(struct phy_device *phydev);
  9834. +int phy_disable_interrupts(struct phy_device *phydev);
  9835. +
  9836. +static inline int phy_read_status(struct phy_device *phydev) {
  9837. + return phydev->drv->read_status(phydev);
  9838. +}
  9839. +
  9840. +int genphy_config_advert(struct phy_device *phydev);
  9841. +int genphy_setup_forced(struct phy_device *phydev);
  9842. +int genphy_restart_aneg(struct phy_device *phydev);
  9843. +int genphy_config_aneg(struct phy_device *phydev);
  9844. +int genphy_update_link(struct phy_device *phydev);
  9845. +int genphy_read_status(struct phy_device *phydev);
  9846. +int genphy_suspend(struct phy_device *phydev);
  9847. +int genphy_resume(struct phy_device *phydev);
  9848. +void phy_driver_unregister(struct phy_driver *drv);
  9849. +int phy_driver_register(struct phy_driver *new_driver);
  9850. +void phy_prepare_link(struct phy_device *phydev,
  9851. + void (*adjust_link)(struct net_device *));
  9852. +void phy_start_machine(struct phy_device *phydev,
  9853. + void (*handler)(struct net_device *));
  9854. +void phy_stop_machine(struct phy_device *phydev);
  9855. +int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  9856. +int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  9857. +int phy_mii_ioctl(struct phy_device *phydev,
  9858. + struct mii_ioctl_data *mii_data, int cmd);
  9859. +int phy_start_interrupts(struct phy_device *phydev);
  9860. +void phy_print_status(struct phy_device *phydev);
  9861. +struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id);
  9862. +void phy_device_free(struct phy_device *phydev);
  9863. +
  9864. +int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
  9865. + int (*run)(struct phy_device *));
  9866. +int phy_register_fixup_for_id(const char *bus_id,
  9867. + int (*run)(struct phy_device *));
  9868. +int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
  9869. + int (*run)(struct phy_device *));
  9870. +int phy_scan_fixups(struct phy_device *phydev);
  9871. +
  9872. +int __init mdio_bus_init(void);
  9873. +void mdio_bus_exit(void);
  9874. +
  9875. +extern struct bus_type mdio_bus_type;
  9876. +#endif /* __PHY_H */