ar71xx.patch 489 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667
  1. diff -Nur linux-2.6.37.orig/arch/mips/Kconfig linux-2.6.37/arch/mips/Kconfig
  2. --- linux-2.6.37.orig/arch/mips/Kconfig 2011-01-05 01:50:19.000000000 +0100
  3. +++ linux-2.6.37/arch/mips/Kconfig 2011-01-11 20:25:48.000000000 +0100
  4. @@ -65,6 +65,23 @@
  5. Support for the Texas Instruments AR7 System-on-a-Chip
  6. family: TNETD7100, 7200 and 7300.
  7. +config ATHEROS_AR71XX
  8. + bool "Atheros AR71xx based boards"
  9. + select CEVT_R4K
  10. + select CSRC_R4K
  11. + select DMA_NONCOHERENT
  12. + select HW_HAS_PCI
  13. + select IRQ_CPU
  14. + select ARCH_REQUIRE_GPIOLIB
  15. + select SYS_HAS_CPU_MIPS32_R1
  16. + select SYS_HAS_CPU_MIPS32_R2
  17. + select SYS_SUPPORTS_32BIT_KERNEL
  18. + select SYS_SUPPORTS_BIG_ENDIAN
  19. + select SYS_HAS_EARLY_PRINTK
  20. + select MIPS_MACHINE
  21. + help
  22. + Support for Atheros AR71xx based boards.
  23. +
  24. config BCM47XX
  25. bool "Broadcom BCM47XX based boards"
  26. select CEVT_R4K
  27. @@ -717,6 +734,7 @@
  28. endchoice
  29. source "arch/mips/alchemy/Kconfig"
  30. +source "arch/mips/ar71xx/Kconfig"
  31. source "arch/mips/bcm63xx/Kconfig"
  32. source "arch/mips/jazz/Kconfig"
  33. source "arch/mips/jz4740/Kconfig"
  34. @@ -880,9 +898,15 @@
  35. config MIPS_DISABLE_OBSOLETE_IDE
  36. bool
  37. +config MYLOADER
  38. + bool
  39. +
  40. config SYNC_R4K
  41. bool
  42. +config MIPS_MACHINE
  43. + def_bool n
  44. +
  45. config NO_IOPORT
  46. def_bool n
  47. diff -Nur linux-2.6.37.orig/arch/mips/Makefile linux-2.6.37/arch/mips/Makefile
  48. --- linux-2.6.37.orig/arch/mips/Makefile 2011-01-05 01:50:19.000000000 +0100
  49. +++ linux-2.6.37/arch/mips/Makefile 2011-01-11 20:25:48.000000000 +0100
  50. @@ -158,6 +158,13 @@
  51. endif
  52. cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
  53. +#
  54. +# Atheros AR71xx
  55. +#
  56. +core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
  57. +cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
  58. +load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
  59. +
  60. cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
  61. cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
  62. cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
  63. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/Kconfig linux-2.6.37/arch/mips/ar71xx/Kconfig
  64. --- linux-2.6.37.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  65. +++ linux-2.6.37/arch/mips/ar71xx/Kconfig 2011-01-11 20:25:48.000000000 +0100
  66. @@ -0,0 +1,264 @@
  67. +if ATHEROS_AR71XX
  68. +
  69. +menu "Atheros AR71xx machine selection"
  70. +
  71. +config AR71XX_MACH_AP81
  72. + bool "Atheros AP81 board support"
  73. + select AR71XX_DEV_M25P80
  74. + select AR71XX_DEV_AR913X_WMAC
  75. + select AR71XX_DEV_GPIO_BUTTONS
  76. + select AR71XX_DEV_LEDS_GPIO
  77. + select AR71XX_DEV_USB
  78. + default n
  79. +
  80. +config AR71XX_MACH_AP83
  81. + bool "Atheros AP83 board support"
  82. + select AR71XX_DEV_AR913X_WMAC
  83. + select AR71XX_DEV_GPIO_BUTTONS
  84. + select AR71XX_DEV_LEDS_GPIO
  85. + select AR71XX_DEV_USB
  86. + default n
  87. +
  88. +config AR71XX_MACH_DIR_600_A1
  89. + bool "D-Link DIR-600 rev. A1 support"
  90. + select AR71XX_DEV_AP91_ETH
  91. + select AR71XX_DEV_AP91_PCI if PCI
  92. + select AR71XX_DEV_M25P80
  93. + select AR71XX_DEV_GPIO_BUTTONS
  94. + select AR71XX_DEV_LEDS_GPIO
  95. + select AR71XX_NVRAM
  96. + default n
  97. +
  98. +config AR71XX_MACH_DIR_615_C1
  99. + bool "D-Link DIR-615 rev. C1 support"
  100. + select AR71XX_DEV_M25P80
  101. + select AR71XX_DEV_AR913X_WMAC
  102. + select AR71XX_DEV_GPIO_BUTTONS
  103. + select AR71XX_DEV_LEDS_GPIO
  104. + select AR71XX_NVRAM
  105. + default n
  106. +
  107. +config AR71XX_MACH_DIR_825_B1
  108. + bool "D-Link DIR-825 rev. B1 board support"
  109. + select AR71XX_DEV_M25P80
  110. + select AR71XX_DEV_AP94_PCI if PCI
  111. + select AR71XX_DEV_GPIO_BUTTONS
  112. + select AR71XX_DEV_LEDS_GPIO
  113. + select AR71XX_DEV_USB
  114. + default n
  115. +
  116. +config AR71XX_MACH_PB42
  117. + bool "Atheros PB42 board support"
  118. + select AR71XX_DEV_M25P80
  119. + select AR71XX_DEV_GPIO_BUTTONS
  120. + select AR71XX_DEV_PB42_PCI if PCI
  121. + default n
  122. +
  123. +config AR71XX_MACH_PB44
  124. + bool "Atheros PB44 board support"
  125. + select AR71XX_DEV_GPIO_BUTTONS
  126. + select AR71XX_DEV_PB42_PCI if PCI
  127. + select AR71XX_DEV_LEDS_GPIO
  128. + select AR71XX_DEV_USB
  129. + default n
  130. +
  131. +config AR71XX_MACH_PB92
  132. + bool "Atheros PB92 board support"
  133. + select AR71XX_DEV_GPIO_BUTTONS
  134. + select AR71XX_DEV_PB9X_PCI if PCI
  135. + select AR71XX_DEV_LEDS_GPIO
  136. + select AR71XX_DEV_USB
  137. + default n
  138. +
  139. +config AR71XX_MACH_AW_NR580
  140. + bool "AzureWave AW-NR580 board support"
  141. + select AR71XX_DEV_M25P80
  142. + select AR71XX_DEV_GPIO_BUTTONS
  143. + select AR71XX_DEV_PB42_PCI if PCI
  144. + select AR71XX_DEV_LEDS_GPIO
  145. + default n
  146. +
  147. +config AR71XX_MACH_WZR_HP_G300NH
  148. + bool "Buffalo WZR-HP-G300NH board support"
  149. + select AR71XX_DEV_AR913X_WMAC
  150. + select AR71XX_DEV_GPIO_BUTTONS
  151. + select AR71XX_DEV_LEDS_GPIO
  152. + select AR71XX_DEV_USB
  153. + default y
  154. +
  155. +config AR71XX_MACH_WP543
  156. + bool "Compex WP543/WPJ543 board support"
  157. + select MYLOADER
  158. + select AR71XX_DEV_M25P80
  159. + select AR71XX_DEV_GPIO_BUTTONS
  160. + select AR71XX_DEV_PB42_PCI if PCI
  161. + select AR71XX_DEV_LEDS_GPIO
  162. + select AR71XX_DEV_USB
  163. + default n
  164. +
  165. +config AR71XX_MACH_WRT160NL
  166. + bool "Linksys WRT160NL board support"
  167. + select AR71XX_DEV_M25P80
  168. + select AR71XX_DEV_AR913X_WMAC
  169. + select AR71XX_DEV_GPIO_BUTTONS
  170. + select AR71XX_DEV_LEDS_GPIO
  171. + select AR71XX_DEV_USB
  172. + select AR71XX_NVRAM
  173. + default n
  174. +
  175. +config AR71XX_MACH_WRT400N
  176. + bool "Linksys WRT400N board support"
  177. + select AR71XX_DEV_AP94_PCI if PCI
  178. + select AR71XX_DEV_M25P80
  179. + select AR71XX_DEV_GPIO_BUTTONS
  180. + select AR71XX_DEV_LEDS_GPIO
  181. + default n
  182. +
  183. +config AR71XX_MACH_RB4XX
  184. + bool "MikroTik RouterBOARD 4xx series support"
  185. + select AR71XX_DEV_GPIO_BUTTONS
  186. + select AR71XX_DEV_LEDS_GPIO
  187. + select AR71XX_DEV_USB
  188. + default n
  189. +
  190. +config AR71XX_MACH_RB750
  191. + bool "MikroTik RouterBOARD 750 support"
  192. + select AR71XX_DEV_AP91_ETH
  193. + default n
  194. +
  195. +config AR71XX_MACH_WNDR3700
  196. + bool "NETGEAR WNDR3700 board support"
  197. + select AR71XX_DEV_M25P80
  198. + select AR71XX_DEV_AP94_PCI if PCI
  199. + select AR71XX_DEV_GPIO_BUTTONS
  200. + select AR71XX_DEV_LEDS_GPIO
  201. + select AR71XX_DEV_USB
  202. + default n
  203. +
  204. +config AR71XX_MACH_WNR2000
  205. + bool "NETGEAR WNR2000 board support"
  206. + select AR71XX_DEV_M25P80
  207. + select AR71XX_DEV_AR913X_WMAC
  208. + select AR71XX_DEV_GPIO_BUTTONS
  209. + select AR71XX_DEV_LEDS_GPIO
  210. + default n
  211. +
  212. +config AR71XX_MACH_MZK_W04NU
  213. + bool "Planex MZK-W04NU board support"
  214. + select AR71XX_DEV_M25P80
  215. + select AR71XX_DEV_AR913X_WMAC
  216. + select AR71XX_DEV_GPIO_BUTTONS
  217. + select AR71XX_DEV_LEDS_GPIO
  218. + select AR71XX_DEV_USB
  219. + default n
  220. +
  221. +config AR71XX_MACH_MZK_W300NH
  222. + bool "Planex MZK-W300NH board support"
  223. + select AR71XX_DEV_M25P80
  224. + select AR71XX_DEV_AR913X_WMAC
  225. + select AR71XX_DEV_GPIO_BUTTONS
  226. + select AR71XX_DEV_LEDS_GPIO
  227. + default n
  228. +
  229. +config AR71XX_MACH_NBG460N
  230. + bool "Zyxel NBG460N/550N/550NH board support"
  231. + select AR71XX_DEV_M25P80
  232. + select AR71XX_DEV_AR913X_WMAC
  233. + select AR71XX_DEV_GPIO_BUTTONS
  234. + select AR71XX_DEV_LEDS_GPIO
  235. + default n
  236. +
  237. +config AR71XX_MACH_TL_WR741ND
  238. + bool "TP-LINK TL-WR741ND support"
  239. + select AR71XX_DEV_M25P80
  240. + select AR71XX_DEV_AP91_ETH
  241. + select AR71XX_DEV_AP91_PCI if PCI
  242. + select AR71XX_DEV_GPIO_BUTTONS
  243. + select AR71XX_DEV_LEDS_GPIO
  244. + default n
  245. +
  246. +config AR71XX_MACH_TL_WR841N_V1
  247. + bool "TP-LINK TL-WR841N v1 support"
  248. + select AR71XX_DEV_M25P80
  249. + select AR71XX_DEV_PB42_PCI if PCI
  250. + select AR71XX_DEV_DSA
  251. + select AR71XX_DEV_GPIO_BUTTONS
  252. + select AR71XX_DEV_LEDS_GPIO
  253. + default n
  254. +
  255. +config AR71XX_MACH_TL_WR941ND
  256. + bool "TP-LINK TL-WR941ND support"
  257. + select AR71XX_DEV_M25P80
  258. + select AR71XX_DEV_AR913X_WMAC
  259. + select AR71XX_DEV_DSA
  260. + select AR71XX_DEV_GPIO_BUTTONS
  261. + select AR71XX_DEV_LEDS_GPIO
  262. + default n
  263. +
  264. +config AR71XX_MACH_TL_WR1043ND
  265. + bool "TP-LINK TL-WR1043ND support"
  266. + select AR71XX_DEV_M25P80
  267. + select AR71XX_DEV_AR913X_WMAC
  268. + select AR71XX_DEV_GPIO_BUTTONS
  269. + select AR71XX_DEV_LEDS_GPIO
  270. + select AR71XX_DEV_USB
  271. + default n
  272. +
  273. +config AR71XX_MACH_TEW_632BRP
  274. + bool "TRENDnet TEW-632BRP support"
  275. + select AR71XX_DEV_M25P80
  276. + select AR71XX_DEV_AR913X_WMAC
  277. + select AR71XX_DEV_GPIO_BUTTONS
  278. + select AR71XX_DEV_LEDS_GPIO
  279. + select AR71XX_NVRAM
  280. + default n
  281. +
  282. +config AR71XX_MACH_UBNT
  283. + bool "Ubiquiti AR71xx based boards support"
  284. + select AR71XX_DEV_M25P80
  285. + select AR71XX_DEV_AP91_PCI if PCI
  286. + select AR71XX_DEV_GPIO_BUTTONS
  287. + select AR71XX_DEV_LEDS_GPIO
  288. + select AR71XX_DEV_PB42_PCI if PCI
  289. + select AR71XX_DEV_USB
  290. + default n
  291. +
  292. +endmenu
  293. +
  294. +config AR71XX_DEV_M25P80
  295. + def_bool n
  296. +
  297. +config AR71XX_DEV_AP91_PCI
  298. + def_bool n
  299. +
  300. +config AR71XX_DEV_AP91_ETH
  301. + def_bool n
  302. +
  303. +config AR71XX_DEV_AP94_PCI
  304. + def_bool n
  305. +
  306. +config AR71XX_DEV_AR913X_WMAC
  307. + def_bool n
  308. +
  309. +config AR71XX_DEV_DSA
  310. + def_bool n
  311. +
  312. +config AR71XX_DEV_GPIO_BUTTONS
  313. + def_bool n
  314. +
  315. +config AR71XX_DEV_LEDS_GPIO
  316. + def_bool n
  317. +
  318. +config AR71XX_DEV_PB42_PCI
  319. + def_bool n
  320. +
  321. +config AR71XX_DEV_PB9X_PCI
  322. + def_bool n
  323. +
  324. +config AR71XX_DEV_USB
  325. + def_bool n
  326. +
  327. +config AR71XX_NVRAM
  328. + def_bool n
  329. +
  330. +endif
  331. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/Makefile linux-2.6.37/arch/mips/ar71xx/Makefile
  332. --- linux-2.6.37.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  333. +++ linux-2.6.37/arch/mips/ar71xx/Makefile 2011-01-11 20:25:48.000000000 +0100
  334. @@ -0,0 +1,54 @@
  335. +#
  336. +# Makefile for the Atheros AR71xx SoC specific parts of the kernel
  337. +#
  338. +# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  339. +# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  340. +#
  341. +# This program is free software; you can redistribute it and/or modify it
  342. +# under the terms of the GNU General Public License version 2 as published
  343. +# by the Free Software Foundation.
  344. +
  345. +obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o
  346. +
  347. +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  348. +obj-$(CONFIG_PCI) += pci.o
  349. +
  350. +obj-$(CONFIG_AR71XX_DEV_AP91_ETH) += dev-ap91-eth.o
  351. +obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o
  352. +obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o
  353. +obj-$(CONFIG_AR71XX_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
  354. +obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o
  355. +obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
  356. +obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o
  357. +obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o
  358. +obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o
  359. +obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o
  360. +obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o
  361. +
  362. +obj-$(CONFIG_AR71XX_NVRAM) += nvram.o
  363. +
  364. +obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o
  365. +obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o
  366. +obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o
  367. +obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o
  368. +obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o
  369. +obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o
  370. +obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o
  371. +obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o
  372. +obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o
  373. +obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o
  374. +obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o
  375. +obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o
  376. +obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o
  377. +obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o
  378. +obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o
  379. +obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o
  380. +obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o
  381. +obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o
  382. +obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o
  383. +obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o
  384. +obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o
  385. +obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o
  386. +obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o
  387. +obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o
  388. +obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o
  389. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.37/arch/mips/ar71xx/ar71xx.c
  390. --- linux-2.6.37.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  391. +++ linux-2.6.37/arch/mips/ar71xx/ar71xx.c 2011-01-11 20:25:48.000000000 +0100
  392. @@ -0,0 +1,177 @@
  393. +/*
  394. + * AR71xx SoC routines
  395. + *
  396. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  397. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  398. + *
  399. + * This program is free software; you can redistribute it and/or modify it
  400. + * under the terms of the GNU General Public License version 2 as published
  401. + * by the Free Software Foundation.
  402. + */
  403. +
  404. +#include <linux/kernel.h>
  405. +#include <linux/module.h>
  406. +#include <linux/types.h>
  407. +#include <linux/mutex.h>
  408. +
  409. +#include <asm/mach-ar71xx/ar71xx.h>
  410. +
  411. +static DEFINE_MUTEX(ar71xx_flash_mutex);
  412. +
  413. +void __iomem *ar71xx_ddr_base;
  414. +EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
  415. +
  416. +void __iomem *ar71xx_pll_base;
  417. +EXPORT_SYMBOL_GPL(ar71xx_pll_base);
  418. +
  419. +void __iomem *ar71xx_reset_base;
  420. +EXPORT_SYMBOL_GPL(ar71xx_reset_base);
  421. +
  422. +void __iomem *ar71xx_gpio_base;
  423. +EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
  424. +
  425. +void __iomem *ar71xx_usb_ctrl_base;
  426. +EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
  427. +
  428. +void ar71xx_device_stop(u32 mask)
  429. +{
  430. + unsigned long flags;
  431. + u32 mask_inv;
  432. + u32 t;
  433. +
  434. + switch (ar71xx_soc) {
  435. + case AR71XX_SOC_AR7130:
  436. + case AR71XX_SOC_AR7141:
  437. + case AR71XX_SOC_AR7161:
  438. + local_irq_save(flags);
  439. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  440. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
  441. + local_irq_restore(flags);
  442. + break;
  443. +
  444. + case AR71XX_SOC_AR7240:
  445. + case AR71XX_SOC_AR7241:
  446. + case AR71XX_SOC_AR7242:
  447. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  448. + local_irq_save(flags);
  449. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  450. + t |= mask;
  451. + t &= ~mask_inv;
  452. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  453. + local_irq_restore(flags);
  454. + break;
  455. +
  456. + case AR71XX_SOC_AR9130:
  457. + case AR71XX_SOC_AR9132:
  458. + local_irq_save(flags);
  459. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  460. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
  461. + local_irq_restore(flags);
  462. + break;
  463. +
  464. + default:
  465. + BUG();
  466. + }
  467. +}
  468. +EXPORT_SYMBOL_GPL(ar71xx_device_stop);
  469. +
  470. +void ar71xx_device_start(u32 mask)
  471. +{
  472. + unsigned long flags;
  473. + u32 mask_inv;
  474. + u32 t;
  475. +
  476. + switch (ar71xx_soc) {
  477. + case AR71XX_SOC_AR7130:
  478. + case AR71XX_SOC_AR7141:
  479. + case AR71XX_SOC_AR7161:
  480. + local_irq_save(flags);
  481. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  482. + ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
  483. + local_irq_restore(flags);
  484. + break;
  485. +
  486. + case AR71XX_SOC_AR7240:
  487. + case AR71XX_SOC_AR7241:
  488. + case AR71XX_SOC_AR7242:
  489. + mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
  490. + local_irq_save(flags);
  491. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  492. + t &= ~mask;
  493. + t |= mask_inv;
  494. + ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
  495. + local_irq_restore(flags);
  496. + break;
  497. +
  498. + case AR71XX_SOC_AR9130:
  499. + case AR71XX_SOC_AR9132:
  500. + local_irq_save(flags);
  501. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  502. + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
  503. + local_irq_restore(flags);
  504. + break;
  505. +
  506. + default:
  507. + BUG();
  508. + }
  509. +}
  510. +EXPORT_SYMBOL_GPL(ar71xx_device_start);
  511. +
  512. +int ar71xx_device_stopped(u32 mask)
  513. +{
  514. + unsigned long flags;
  515. + u32 t;
  516. +
  517. + switch (ar71xx_soc) {
  518. + case AR71XX_SOC_AR7130:
  519. + case AR71XX_SOC_AR7141:
  520. + case AR71XX_SOC_AR7161:
  521. + local_irq_save(flags);
  522. + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
  523. + local_irq_restore(flags);
  524. + break;
  525. +
  526. + case AR71XX_SOC_AR7240:
  527. + case AR71XX_SOC_AR7241:
  528. + case AR71XX_SOC_AR7242:
  529. + local_irq_save(flags);
  530. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  531. + local_irq_restore(flags);
  532. + break;
  533. +
  534. + case AR71XX_SOC_AR9130:
  535. + case AR71XX_SOC_AR9132:
  536. + local_irq_save(flags);
  537. + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
  538. + local_irq_restore(flags);
  539. + break;
  540. +
  541. + default:
  542. + BUG();
  543. + }
  544. +
  545. + return ((t & mask) == mask);
  546. +}
  547. +EXPORT_SYMBOL_GPL(ar71xx_device_stopped);
  548. +
  549. +void ar71xx_ddr_flush(u32 reg)
  550. +{
  551. + ar71xx_ddr_wr(reg, 1);
  552. + while ((ar71xx_ddr_rr(reg) & 0x1));
  553. +
  554. + ar71xx_ddr_wr(reg, 1);
  555. + while ((ar71xx_ddr_rr(reg) & 0x1));
  556. +}
  557. +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
  558. +
  559. +void ar71xx_flash_acquire(void)
  560. +{
  561. + mutex_lock(&ar71xx_flash_mutex);
  562. +}
  563. +EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
  564. +
  565. +void ar71xx_flash_release(void)
  566. +{
  567. + mutex_unlock(&ar71xx_flash_mutex);
  568. +}
  569. +EXPORT_SYMBOL_GPL(ar71xx_flash_release);
  570. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-eth.c linux-2.6.37/arch/mips/ar71xx/dev-ap91-eth.c
  571. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-eth.c 1970-01-01 01:00:00.000000000 +0100
  572. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap91-eth.c 2011-01-11 20:25:48.000000000 +0100
  573. @@ -0,0 +1,70 @@
  574. +/*
  575. + * Atheros AP91 reference board ethernet initialization
  576. + *
  577. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  578. + *
  579. + * This program is free software; you can redistribute it and/or modify it
  580. + * under the terms of the GNU General Public License version 2 as published
  581. + * by the Free Software Foundation.
  582. + */
  583. +
  584. +#include "devices.h"
  585. +#include "dev-dsa.h"
  586. +#include "dev-ap91-eth.h"
  587. +
  588. +static struct dsa_chip_data ap91_dsa_chip = {
  589. + .port_names[0] = "cpu",
  590. + .port_names[1] = "lan1",
  591. + .port_names[2] = "lan2",
  592. + .port_names[3] = "lan3",
  593. + .port_names[4] = "lan4",
  594. +};
  595. +
  596. +static struct dsa_platform_data ap91_dsa_data = {
  597. + .nr_chips = 1,
  598. + .chip = &ap91_dsa_chip,
  599. +};
  600. +
  601. +static void ap91_eth_set_port_name(unsigned port, const char *name)
  602. +{
  603. + if (port < 1 || port > 5)
  604. + return;
  605. +
  606. + if (name)
  607. + ap91_dsa_chip.port_names[port] = (char *) name;
  608. +}
  609. +
  610. +void __init ap91_eth_init(u8 *mac_addr, const char *port_names[])
  611. +{
  612. + if (mac_addr)
  613. + ar71xx_set_mac_base(mac_addr);
  614. +
  615. + if (port_names) {
  616. + int i;
  617. +
  618. + for (i = 0; i < AP91_ETH_NUM_PORT_NAMES; i++)
  619. + ap91_eth_set_port_name(i + 1, port_names[i]);
  620. + }
  621. +
  622. + /* WAN port */
  623. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  624. + ar71xx_eth0_data.speed = SPEED_100;
  625. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  626. + ar71xx_eth0_data.fifo_cfg1 = 0x0fff0000;
  627. + ar71xx_eth0_data.fifo_cfg2 = 0x00001fff;
  628. + ar71xx_eth0_data.fifo_cfg3 = 0x008001ff;
  629. +
  630. + /* LAN ports */
  631. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  632. + ar71xx_eth1_data.speed = SPEED_1000;
  633. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  634. + ar71xx_eth1_data.fifo_cfg1 = 0x0fff0000;
  635. + ar71xx_eth1_data.fifo_cfg2 = 0x00001fff;
  636. + ar71xx_eth1_data.fifo_cfg3 = 0x008001ff;
  637. +
  638. + ar71xx_add_device_mdio(0x0);
  639. + ar71xx_add_device_eth(1);
  640. + ar71xx_add_device_eth(0);
  641. +
  642. + ar71xx_add_device_dsa(1, &ap91_dsa_data);
  643. +}
  644. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-eth.h linux-2.6.37/arch/mips/ar71xx/dev-ap91-eth.h
  645. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-eth.h 1970-01-01 01:00:00.000000000 +0100
  646. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap91-eth.h 2011-01-11 20:25:48.000000000 +0100
  647. @@ -0,0 +1,23 @@
  648. +/*
  649. + * Atheros AP91 reference board ethernet initialization
  650. + *
  651. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  652. + *
  653. + * This program is free software; you can redistribute it and/or modify it
  654. + * under the terms of the GNU General Public License version 2 as published
  655. + * by the Free Software Foundation.
  656. + */
  657. +
  658. +#ifndef _AR71XX_DEV_AP91_ETH_H
  659. +#define _AR71XX_DEV_AP91_ETH_H
  660. +
  661. +#define AP91_ETH_NUM_PORT_NAMES 4
  662. +
  663. +#if defined(CONFIG_AR71XX_DEV_AP91_ETH)
  664. +void ap91_eth_init(u8 *mac_addr, const char *port_names[]) __init;
  665. +#else
  666. +static inline void ap91_eth_init(u8 *mac_addr) { }
  667. +#endif
  668. +
  669. +#endif /* _AR71XX_DEV_AP91_ETH_H */
  670. +
  671. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.37/arch/mips/ar71xx/dev-ap91-pci.c
  672. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100
  673. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap91-pci.c 2011-01-11 20:25:48.000000000 +0100
  674. @@ -0,0 +1,114 @@
  675. +/*
  676. + * Atheros AP91 reference board PCI initialization
  677. + *
  678. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  679. + *
  680. + * This program is free software; you can redistribute it and/or modify it
  681. + * under the terms of the GNU General Public License version 2 as published
  682. + * by the Free Software Foundation.
  683. + */
  684. +
  685. +#include <linux/pci.h>
  686. +#include <linux/ath9k_platform.h>
  687. +#include <linux/delay.h>
  688. +
  689. +#include <asm/mach-ar71xx/ar71xx.h>
  690. +#include <asm/mach-ar71xx/pci.h>
  691. +
  692. +#include "dev-ap91-pci.h"
  693. +
  694. +static struct ath9k_platform_data ap91_wmac_data;
  695. +static char ap91_wmac_mac[6];
  696. +static int ap91_pci_fixup_enabled;
  697. +
  698. +static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
  699. + {
  700. + .slot = 0,
  701. + .pin = 1,
  702. + .irq = AR71XX_PCI_IRQ_DEV0,
  703. + }
  704. +};
  705. +
  706. +static int ap91_pci_plat_dev_init(struct pci_dev *dev)
  707. +{
  708. + switch(PCI_SLOT(dev->devfn)) {
  709. + case 0:
  710. + dev->dev.platform_data = &ap91_wmac_data;
  711. + break;
  712. + }
  713. +
  714. + return 0;
  715. +}
  716. +
  717. +static void ap91_pci_fixup(struct pci_dev *dev)
  718. +{
  719. + void __iomem *mem;
  720. + u16 *cal_data;
  721. + u16 cmd;
  722. + u32 val;
  723. +
  724. + if (!ap91_pci_fixup_enabled)
  725. + return;
  726. +
  727. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  728. +
  729. + cal_data = ap91_wmac_data.eeprom_data;
  730. + if (*cal_data != 0xa55a) {
  731. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  732. + pci_name(dev));
  733. + return;
  734. + }
  735. +
  736. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  737. + if (!mem) {
  738. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  739. + pci_name(dev));
  740. + return;
  741. + }
  742. +
  743. + /* Setup the PCI device to allow access to the internal registers */
  744. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
  745. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  746. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  747. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  748. +
  749. + /* set pointer to first reg address */
  750. + cal_data += 3;
  751. + while (*cal_data != 0xffff) {
  752. + u32 reg;
  753. + reg = *cal_data++;
  754. + val = *cal_data++;
  755. + val |= (*cal_data++) << 16;
  756. +
  757. + __raw_writel(val, mem + reg);
  758. + udelay(100);
  759. + }
  760. +
  761. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  762. + dev->vendor = val & 0xffff;
  763. + dev->device = (val >> 16) & 0xffff;
  764. +
  765. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  766. + dev->revision = val & 0xff;
  767. + dev->class = val >> 8; /* upper 3 bytes */
  768. +
  769. + iounmap(mem);
  770. +}
  771. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup);
  772. +
  773. +void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
  774. +{
  775. + if (cal_data)
  776. + memcpy(ap91_wmac_data.eeprom_data, cal_data,
  777. + sizeof(ap91_wmac_data.eeprom_data));
  778. +
  779. + if (mac_addr) {
  780. + memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac));
  781. + ap91_wmac_data.macaddr = ap91_wmac_mac;
  782. + }
  783. +
  784. + ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
  785. + ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
  786. +
  787. + ap91_pci_fixup_enabled = 1;
  788. +}
  789. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.37/arch/mips/ar71xx/dev-ap91-pci.h
  790. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100
  791. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap91-pci.h 2011-01-11 20:25:48.000000000 +0100
  792. @@ -0,0 +1,21 @@
  793. +/*
  794. + * Atheros AP91 reference board PCI initialization
  795. + *
  796. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  797. + *
  798. + * This program is free software; you can redistribute it and/or modify it
  799. + * under the terms of the GNU General Public License version 2 as published
  800. + * by the Free Software Foundation.
  801. + */
  802. +
  803. +#ifndef _AR71XX_DEV_AP91_PCI_H
  804. +#define _AR71XX_DEV_AP91_PCI_H
  805. +
  806. +#if defined(CONFIG_AR71XX_DEV_AP91_PCI)
  807. +void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init;
  808. +#else
  809. +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { }
  810. +#endif
  811. +
  812. +#endif /* _AR71XX_DEV_AP91_PCI_H */
  813. +
  814. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.37/arch/mips/ar71xx/dev-ap94-pci.c
  815. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100
  816. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap94-pci.c 2011-01-11 20:25:48.000000000 +0100
  817. @@ -0,0 +1,159 @@
  818. +/*
  819. + * Atheros AP94 reference board PCI initialization
  820. + *
  821. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  822. + *
  823. + * This program is free software; you can redistribute it and/or modify it
  824. + * under the terms of the GNU General Public License version 2 as published
  825. + * by the Free Software Foundation.
  826. + */
  827. +
  828. +#include <linux/pci.h>
  829. +#include <linux/ath9k_platform.h>
  830. +#include <linux/delay.h>
  831. +
  832. +#include <asm/mach-ar71xx/ar71xx.h>
  833. +#include <asm/mach-ar71xx/pci.h>
  834. +
  835. +#include "dev-ap94-pci.h"
  836. +
  837. +static struct ath9k_platform_data ap94_wmac0_data;
  838. +static struct ath9k_platform_data ap94_wmac1_data;
  839. +static char ap94_wmac0_mac[6];
  840. +static char ap94_wmac1_mac[6];
  841. +static int ap94_pci_fixup_enabled;
  842. +
  843. +static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
  844. + {
  845. + .slot = 0,
  846. + .pin = 1,
  847. + .irq = AR71XX_PCI_IRQ_DEV0,
  848. + }, {
  849. + .slot = 1,
  850. + .pin = 1,
  851. + .irq = AR71XX_PCI_IRQ_DEV1,
  852. + }
  853. +};
  854. +
  855. +static int ap94_pci_plat_dev_init(struct pci_dev *dev)
  856. +{
  857. + switch(PCI_SLOT(dev->devfn)) {
  858. + case 17:
  859. + dev->dev.platform_data = &ap94_wmac0_data;
  860. + break;
  861. +
  862. + case 18:
  863. + dev->dev.platform_data = &ap94_wmac1_data;
  864. + break;
  865. + }
  866. +
  867. + return 0;
  868. +}
  869. +
  870. +static void ap94_pci_fixup(struct pci_dev *dev)
  871. +{
  872. + void __iomem *mem;
  873. + u16 *cal_data;
  874. + u16 cmd;
  875. + u32 bar0;
  876. + u32 val;
  877. +
  878. + if (!ap94_pci_fixup_enabled)
  879. + return;
  880. +
  881. + switch (PCI_SLOT(dev->devfn)) {
  882. + case 17:
  883. + cal_data = ap94_wmac0_data.eeprom_data;
  884. + break;
  885. + case 18:
  886. + cal_data = ap94_wmac1_data.eeprom_data;
  887. + break;
  888. + default:
  889. + return;
  890. + }
  891. +
  892. + if (*cal_data != 0xa55a) {
  893. + printk(KERN_ERR "PCI: no calibration data found for %s\n",
  894. + pci_name(dev));
  895. + return;
  896. + }
  897. +
  898. + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
  899. + if (!mem) {
  900. + printk(KERN_ERR "PCI: ioremap error for device %s\n",
  901. + pci_name(dev));
  902. + return;
  903. + }
  904. +
  905. + printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
  906. +
  907. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  908. +
  909. + /* Setup the PCI device to allow access to the internal registers */
  910. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE);
  911. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  912. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  913. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  914. +
  915. + /* set pointer to first reg address */
  916. + cal_data += 3;
  917. + while (*cal_data != 0xffff) {
  918. + u32 reg;
  919. + reg = *cal_data++;
  920. + val = *cal_data++;
  921. + val |= (*cal_data++) << 16;
  922. +
  923. + __raw_writel(val, mem + reg);
  924. + udelay(100);
  925. + }
  926. +
  927. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  928. + dev->vendor = val & 0xffff;
  929. + dev->device = (val >> 16) & 0xffff;
  930. +
  931. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  932. + dev->revision = val & 0xff;
  933. + dev->class = val >> 8; /* upper 3 bytes */
  934. +
  935. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  936. + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
  937. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  938. +
  939. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
  940. +
  941. + iounmap(mem);
  942. +}
  943. +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup);
  944. +
  945. +void __init ap94_pci_enable_quirk_wndr3700(void)
  946. +{
  947. + ap94_wmac0_data.quirk_wndr3700 = 1;
  948. + ap94_wmac1_data.quirk_wndr3700 = 1;
  949. +}
  950. +
  951. +void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  952. + u8 *cal_data1, u8 *mac_addr1)
  953. +{
  954. + if (cal_data0)
  955. + memcpy(ap94_wmac0_data.eeprom_data, cal_data0,
  956. + sizeof(ap94_wmac0_data.eeprom_data));
  957. +
  958. + if (cal_data1)
  959. + memcpy(ap94_wmac1_data.eeprom_data, cal_data1,
  960. + sizeof(ap94_wmac1_data.eeprom_data));
  961. +
  962. + if (mac_addr0) {
  963. + memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac));
  964. + ap94_wmac0_data.macaddr = ap94_wmac0_mac;
  965. + }
  966. +
  967. + if (mac_addr1) {
  968. + memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac));
  969. + ap94_wmac1_data.macaddr = ap94_wmac1_mac;
  970. + }
  971. +
  972. + ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
  973. + ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
  974. +
  975. + ap94_pci_fixup_enabled = 1;
  976. +}
  977. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.37/arch/mips/ar71xx/dev-ap94-pci.h
  978. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100
  979. +++ linux-2.6.37/arch/mips/ar71xx/dev-ap94-pci.h 2011-01-11 20:25:48.000000000 +0100
  980. @@ -0,0 +1,28 @@
  981. +/*
  982. + * Atheros AP94 reference board PCI initialization
  983. + *
  984. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  985. + *
  986. + * This program is free software; you can redistribute it and/or modify it
  987. + * under the terms of the GNU General Public License version 2 as published
  988. + * by the Free Software Foundation.
  989. + */
  990. +
  991. +#ifndef _AR71XX_DEV_AP94_PCI_H
  992. +#define _AR71XX_DEV_AP94_PCI_H
  993. +
  994. +#if defined(CONFIG_AR71XX_DEV_AP94_PCI)
  995. +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  996. + u8 *cal_data1, u8 *mac_addr1) __init;
  997. +
  998. +void ap94_pci_enable_quirk_wndr3700(void) __init;
  999. +
  1000. +#else
  1001. +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
  1002. + u8 *cal_data1, u8 *mac_addr1) {}
  1003. +
  1004. +static inline void ap94_pci_enable_quirk_wndr3700(void) {}
  1005. +#endif
  1006. +
  1007. +#endif /* _AR71XX_DEV_AP94_PCI_H */
  1008. +
  1009. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.37/arch/mips/ar71xx/dev-ar913x-wmac.c
  1010. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ar913x-wmac.c 1970-01-01 01:00:00.000000000 +0100
  1011. +++ linux-2.6.37/arch/mips/ar71xx/dev-ar913x-wmac.c 2011-01-11 20:25:48.000000000 +0100
  1012. @@ -0,0 +1,68 @@
  1013. +/*
  1014. + * Atheros AR913x SoC built-in WMAC device support
  1015. + *
  1016. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1017. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1018. + *
  1019. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1020. + *
  1021. + * This program is free software; you can redistribute it and/or modify it
  1022. + * under the terms of the GNU General Public License version 2 as published
  1023. + * by the Free Software Foundation.
  1024. + */
  1025. +
  1026. +#include <linux/kernel.h>
  1027. +#include <linux/init.h>
  1028. +#include <linux/delay.h>
  1029. +#include <linux/etherdevice.h>
  1030. +#include <linux/platform_device.h>
  1031. +#include <linux/ath9k_platform.h>
  1032. +
  1033. +#include <asm/mach-ar71xx/ar71xx.h>
  1034. +
  1035. +#include "dev-ar913x-wmac.h"
  1036. +
  1037. +static struct ath9k_platform_data ar913x_wmac_data;
  1038. +static char ar913x_wmac_mac[6];
  1039. +
  1040. +static struct resource ar913x_wmac_resources[] = {
  1041. + {
  1042. + .start = AR91XX_WMAC_BASE,
  1043. + .end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
  1044. + .flags = IORESOURCE_MEM,
  1045. + }, {
  1046. + .start = AR71XX_CPU_IRQ_IP2,
  1047. + .end = AR71XX_CPU_IRQ_IP2,
  1048. + .flags = IORESOURCE_IRQ,
  1049. + },
  1050. +};
  1051. +
  1052. +static struct platform_device ar913x_wmac_device = {
  1053. + .name = "ath9k",
  1054. + .id = -1,
  1055. + .resource = ar913x_wmac_resources,
  1056. + .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
  1057. + .dev = {
  1058. + .platform_data = &ar913x_wmac_data,
  1059. + },
  1060. +};
  1061. +
  1062. +void __init ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr)
  1063. +{
  1064. + if (cal_data)
  1065. + memcpy(ar913x_wmac_data.eeprom_data, cal_data,
  1066. + sizeof(ar913x_wmac_data.eeprom_data));
  1067. +
  1068. + if (mac_addr) {
  1069. + memcpy(ar913x_wmac_mac, mac_addr, sizeof(ar913x_wmac_mac));
  1070. + ar913x_wmac_data.macaddr = ar913x_wmac_mac;
  1071. + }
  1072. +
  1073. + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
  1074. + mdelay(10);
  1075. +
  1076. + ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
  1077. + mdelay(10);
  1078. +
  1079. + platform_device_register(&ar913x_wmac_device);
  1080. +}
  1081. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-ar913x-wmac.h linux-2.6.37/arch/mips/ar71xx/dev-ar913x-wmac.h
  1082. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-ar913x-wmac.h 1970-01-01 01:00:00.000000000 +0100
  1083. +++ linux-2.6.37/arch/mips/ar71xx/dev-ar913x-wmac.h 2011-01-11 20:25:48.000000000 +0100
  1084. @@ -0,0 +1,19 @@
  1085. +/*
  1086. + * Atheros AR913x SoC built-in WMAC device support
  1087. + *
  1088. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1089. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1090. + *
  1091. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1092. + *
  1093. + * This program is free software; you can redistribute it and/or modify it
  1094. + * under the terms of the GNU General Public License version 2 as published
  1095. + * by the Free Software Foundation.
  1096. + */
  1097. +
  1098. +#ifndef _AR71XX_DEV_AR913X_WMAC_H
  1099. +#define _AR71XX_DEV_AR913X_WMAC_H
  1100. +
  1101. +void ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init;
  1102. +
  1103. +#endif /* _AR71XX_DEV_AR913X_WMAC_H */
  1104. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.37/arch/mips/ar71xx/dev-dsa.c
  1105. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100
  1106. +++ linux-2.6.37/arch/mips/ar71xx/dev-dsa.c 2011-01-11 20:25:48.000000000 +0100
  1107. @@ -0,0 +1,50 @@
  1108. +/*
  1109. + * Atheros AR71xx DSA switch device support
  1110. + *
  1111. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1112. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1113. + *
  1114. + * This program is free software; you can redistribute it and/or modify it
  1115. + * under the terms of the GNU General Public License version 2 as published
  1116. + * by the Free Software Foundation.
  1117. + */
  1118. +
  1119. +#include <linux/init.h>
  1120. +#include <linux/platform_device.h>
  1121. +
  1122. +#include <asm/mach-ar71xx/ar71xx.h>
  1123. +
  1124. +#include "devices.h"
  1125. +#include "dev-dsa.h"
  1126. +
  1127. +static struct platform_device ar71xx_dsa_switch_device = {
  1128. + .name = "dsa",
  1129. + .id = 0,
  1130. +};
  1131. +
  1132. +void __init ar71xx_add_device_dsa(unsigned int id,
  1133. + struct dsa_platform_data *d)
  1134. +{
  1135. + int i;
  1136. +
  1137. + switch (id) {
  1138. + case 0:
  1139. + d->netdev = &ar71xx_eth0_device.dev;
  1140. + break;
  1141. + case 1:
  1142. + d->netdev = &ar71xx_eth1_device.dev;
  1143. + break;
  1144. + default:
  1145. + printk(KERN_ERR
  1146. + "ar71xx: invalid ethernet id %d for DSA switch\n",
  1147. + id);
  1148. + return;
  1149. + }
  1150. +
  1151. + for (i = 0; i < d->nr_chips; i++)
  1152. + d->chip[i].mii_bus = &ar71xx_mdio_device.dev;
  1153. +
  1154. + ar71xx_dsa_switch_device.dev.platform_data = d;
  1155. +
  1156. + platform_device_register(&ar71xx_dsa_switch_device);
  1157. +}
  1158. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.37/arch/mips/ar71xx/dev-dsa.h
  1159. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100
  1160. +++ linux-2.6.37/arch/mips/ar71xx/dev-dsa.h 2011-01-11 20:25:48.000000000 +0100
  1161. @@ -0,0 +1,20 @@
  1162. +/*
  1163. + * Atheros AR71xx DSA switch device support
  1164. + *
  1165. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1166. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1167. + *
  1168. + * This program is free software; you can redistribute it and/or modify it
  1169. + * under the terms of the GNU General Public License version 2 as published
  1170. + * by the Free Software Foundation.
  1171. + */
  1172. +
  1173. +#ifndef _AR71XX_DEV_DSA_H
  1174. +#define _AR71XX_DEV_DSA_H
  1175. +
  1176. +#include <net/dsa.h>
  1177. +
  1178. +void ar71xx_add_device_dsa(unsigned int id,
  1179. + struct dsa_platform_data *d) __init;
  1180. +
  1181. +#endif /* _AR71XX_DEV_DSA_H */
  1182. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.37/arch/mips/ar71xx/dev-gpio-buttons.c
  1183. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100
  1184. +++ linux-2.6.37/arch/mips/ar71xx/dev-gpio-buttons.c 2011-01-11 20:25:48.000000000 +0100
  1185. @@ -0,0 +1,58 @@
  1186. +/*
  1187. + * Atheros AR71xx GPIO button support
  1188. + *
  1189. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1190. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1191. + *
  1192. + * This program is free software; you can redistribute it and/or modify it
  1193. + * under the terms of the GNU General Public License version 2 as published
  1194. + * by the Free Software Foundation.
  1195. + */
  1196. +
  1197. +#include "linux/init.h"
  1198. +#include <linux/platform_device.h>
  1199. +
  1200. +#include "dev-gpio-buttons.h"
  1201. +
  1202. +void __init ar71xx_add_device_gpio_buttons(int id,
  1203. + unsigned poll_interval,
  1204. + unsigned nbuttons,
  1205. + struct gpio_button *buttons)
  1206. +{
  1207. + struct platform_device *pdev;
  1208. + struct gpio_buttons_platform_data pdata;
  1209. + struct gpio_button *p;
  1210. + int err;
  1211. +
  1212. + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
  1213. + if (!p)
  1214. + return;
  1215. +
  1216. + memcpy(p, buttons, nbuttons * sizeof(*p));
  1217. +
  1218. + pdev = platform_device_alloc("gpio-buttons", id);
  1219. + if (!pdev)
  1220. + goto err_free_buttons;
  1221. +
  1222. + memset(&pdata, 0, sizeof(pdata));
  1223. + pdata.poll_interval = poll_interval;
  1224. + pdata.nbuttons = nbuttons;
  1225. + pdata.buttons = p;
  1226. +
  1227. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1228. + if (err)
  1229. + goto err_put_pdev;
  1230. +
  1231. +
  1232. + err = platform_device_add(pdev);
  1233. + if (err)
  1234. + goto err_put_pdev;
  1235. +
  1236. + return;
  1237. +
  1238. +err_put_pdev:
  1239. + platform_device_put(pdev);
  1240. +
  1241. +err_free_buttons:
  1242. + kfree(p);
  1243. +}
  1244. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.37/arch/mips/ar71xx/dev-gpio-buttons.h
  1245. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100
  1246. +++ linux-2.6.37/arch/mips/ar71xx/dev-gpio-buttons.h 2011-01-11 20:25:48.000000000 +0100
  1247. @@ -0,0 +1,25 @@
  1248. +/*
  1249. + * Atheros AR71xx GPIO button support
  1250. + *
  1251. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1252. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1253. + *
  1254. + * This program is free software; you can redistribute it and/or modify it
  1255. + * under the terms of the GNU General Public License version 2 as published
  1256. + * by the Free Software Foundation.
  1257. + */
  1258. +
  1259. +#ifndef _AR71XX_DEV_GPIO_BUTTONS_H
  1260. +#define _AR71XX_DEV_GPIO_BUTTONS_H
  1261. +
  1262. +#include <linux/input.h>
  1263. +#include <linux/gpio_buttons.h>
  1264. +
  1265. +#include <asm/mach-ar71xx/platform.h>
  1266. +
  1267. +void ar71xx_add_device_gpio_buttons(int id,
  1268. + unsigned poll_interval,
  1269. + unsigned nbuttons,
  1270. + struct gpio_button *buttons) __init;
  1271. +
  1272. +#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */
  1273. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.37/arch/mips/ar71xx/dev-leds-gpio.c
  1274. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100
  1275. +++ linux-2.6.37/arch/mips/ar71xx/dev-leds-gpio.c 2011-01-11 20:25:48.000000000 +0100
  1276. @@ -0,0 +1,57 @@
  1277. +/*
  1278. + * Atheros AR71xx GPIO LED device support
  1279. + *
  1280. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1281. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1282. + *
  1283. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1284. + *
  1285. + * This program is free software; you can redistribute it and/or modify it
  1286. + * under the terms of the GNU General Public License version 2 as published
  1287. + * by the Free Software Foundation.
  1288. + */
  1289. +
  1290. +#include <linux/init.h>
  1291. +#include <linux/platform_device.h>
  1292. +#include <linux/slab.h>
  1293. +
  1294. +#include "dev-leds-gpio.h"
  1295. +
  1296. +void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
  1297. + struct gpio_led *leds)
  1298. +{
  1299. + struct platform_device *pdev;
  1300. + struct gpio_led_platform_data pdata;
  1301. + struct gpio_led *p;
  1302. + int err;
  1303. +
  1304. + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
  1305. + if (!p)
  1306. + return;
  1307. +
  1308. + memcpy(p, leds, num_leds * sizeof(*p));
  1309. +
  1310. + pdev = platform_device_alloc("leds-gpio", id);
  1311. + if (!pdev)
  1312. + goto err_free_leds;
  1313. +
  1314. + memset(&pdata, 0, sizeof(pdata));
  1315. + pdata.num_leds = num_leds;
  1316. + pdata.leds = p;
  1317. +
  1318. + err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
  1319. + if (err)
  1320. + goto err_put_pdev;
  1321. +
  1322. + err = platform_device_add(pdev);
  1323. + if (err)
  1324. + goto err_put_pdev;
  1325. +
  1326. + return;
  1327. +
  1328. +err_put_pdev:
  1329. + platform_device_put(pdev);
  1330. +
  1331. +err_free_leds:
  1332. + kfree(p);
  1333. +}
  1334. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.37/arch/mips/ar71xx/dev-leds-gpio.h
  1335. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100
  1336. +++ linux-2.6.37/arch/mips/ar71xx/dev-leds-gpio.h 2011-01-11 20:25:48.000000000 +0100
  1337. @@ -0,0 +1,21 @@
  1338. +/*
  1339. + * Atheros AR71xx GPIO LED device support
  1340. + *
  1341. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1342. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1343. + *
  1344. + * This program is free software; you can redistribute it and/or modify it
  1345. + * under the terms of the GNU General Public License version 2 as published
  1346. + * by the Free Software Foundation.
  1347. + */
  1348. +
  1349. +#ifndef _AR71XX_DEV_LEDS_GPIO_H
  1350. +#define _AR71XX_DEV_LEDS_GPIO_H
  1351. +
  1352. +#include <linux/leds.h>
  1353. +
  1354. +void ar71xx_add_device_leds_gpio(int id,
  1355. + unsigned num_leds,
  1356. + struct gpio_led *leds) __init;
  1357. +
  1358. +#endif /* _AR71XX_DEV_LEDS_GPIO_H */
  1359. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.37/arch/mips/ar71xx/dev-m25p80.c
  1360. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100
  1361. +++ linux-2.6.37/arch/mips/ar71xx/dev-m25p80.c 2011-01-11 20:25:48.000000000 +0100
  1362. @@ -0,0 +1,30 @@
  1363. +/*
  1364. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1365. + *
  1366. + * This program is free software; you can redistribute it and/or modify it
  1367. + * under the terms of the GNU General Public License version 2 as published
  1368. + * by the Free Software Foundation.
  1369. + */
  1370. +
  1371. +#include <linux/init.h>
  1372. +#include <linux/spi/spi.h>
  1373. +#include <linux/spi/flash.h>
  1374. +
  1375. +#include "devices.h"
  1376. +#include "dev-m25p80.h"
  1377. +
  1378. +static struct spi_board_info ar71xx_spi_info[] = {
  1379. + {
  1380. + .bus_num = 0,
  1381. + .chip_select = 0,
  1382. + .max_speed_hz = 25000000,
  1383. + .modalias = "m25p80",
  1384. + }
  1385. +};
  1386. +
  1387. +void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata)
  1388. +{
  1389. + ar71xx_spi_info[0].platform_data = pdata;
  1390. + ar71xx_add_device_spi(NULL, ar71xx_spi_info,
  1391. + ARRAY_SIZE(ar71xx_spi_info));
  1392. +}
  1393. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.37/arch/mips/ar71xx/dev-m25p80.h
  1394. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100
  1395. +++ linux-2.6.37/arch/mips/ar71xx/dev-m25p80.h 2011-01-11 20:25:48.000000000 +0100
  1396. @@ -0,0 +1,16 @@
  1397. +/*
  1398. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  1399. + *
  1400. + * This program is free software; you can redistribute it and/or modify it
  1401. + * under the terms of the GNU General Public License version 2 as published
  1402. + * by the Free Software Foundation.
  1403. + */
  1404. +
  1405. +#ifndef _AR71XX_DEV_M25P80_H
  1406. +#define _AR71XX_DEV_M25P80_H
  1407. +
  1408. +#include <linux/spi/flash.h>
  1409. +
  1410. +void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init;
  1411. +
  1412. +#endif /* _AR71XX_DEV_M25P80_H */
  1413. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.37/arch/mips/ar71xx/dev-pb42-pci.c
  1414. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100
  1415. +++ linux-2.6.37/arch/mips/ar71xx/dev-pb42-pci.c 2011-01-11 20:25:48.000000000 +0100
  1416. @@ -0,0 +1,40 @@
  1417. +/*
  1418. + * Atheros PB42 reference board PCI initialization
  1419. + *
  1420. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1421. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1422. + *
  1423. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1424. + *
  1425. + * This program is free software; you can redistribute it and/or modify it
  1426. + * under the terms of the GNU General Public License version 2 as published
  1427. + * by the Free Software Foundation.
  1428. + */
  1429. +
  1430. +#include <linux/pci.h>
  1431. +
  1432. +#include <asm/mach-ar71xx/ar71xx.h>
  1433. +#include <asm/mach-ar71xx/pci.h>
  1434. +
  1435. +#include "dev-pb42-pci.h"
  1436. +
  1437. +static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
  1438. + {
  1439. + .slot = 0,
  1440. + .pin = 1,
  1441. + .irq = AR71XX_PCI_IRQ_DEV0,
  1442. + }, {
  1443. + .slot = 1,
  1444. + .pin = 1,
  1445. + .irq = AR71XX_PCI_IRQ_DEV1,
  1446. + }, {
  1447. + .slot = 2,
  1448. + .pin = 1,
  1449. + .irq = AR71XX_PCI_IRQ_DEV2,
  1450. + }
  1451. +};
  1452. +
  1453. +void __init pb42_pci_init(void)
  1454. +{
  1455. + ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
  1456. +}
  1457. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.37/arch/mips/ar71xx/dev-pb42-pci.h
  1458. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100
  1459. +++ linux-2.6.37/arch/mips/ar71xx/dev-pb42-pci.h 2011-01-11 20:25:48.000000000 +0100
  1460. @@ -0,0 +1,21 @@
  1461. +/*
  1462. + * Atheros PB42 reference board PCI initialization
  1463. + *
  1464. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1465. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1466. + *
  1467. + * This program is free software; you can redistribute it and/or modify it
  1468. + * under the terms of the GNU General Public License version 2 as published
  1469. + * by the Free Software Foundation.
  1470. + */
  1471. +
  1472. +#ifndef _AR71XX_DEV_PB42_PCI_H
  1473. +#define _AR71XX_DEV_PB42_PCI_H
  1474. +
  1475. +#if defined(CONFIG_AR71XX_DEV_PB42_PCI)
  1476. +void pb42_pci_init(void) __init;
  1477. +#else
  1478. +static inline void pb42_pci_init(void) { }
  1479. +#endif
  1480. +
  1481. +#endif /* _AR71XX_DEV_PB42_PCI_H */
  1482. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.37/arch/mips/ar71xx/dev-pb9x-pci.c
  1483. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100
  1484. +++ linux-2.6.37/arch/mips/ar71xx/dev-pb9x-pci.c 2011-01-11 20:25:48.000000000 +0100
  1485. @@ -0,0 +1,33 @@
  1486. +/*
  1487. + * Atheros PB9x reference board PCI initialization
  1488. + *
  1489. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1490. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1491. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1492. + *
  1493. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1494. + *
  1495. + * This program is free software; you can redistribute it and/or modify it
  1496. + * under the terms of the GNU General Public License version 2 as published
  1497. + * by the Free Software Foundation.
  1498. + */
  1499. +
  1500. +#include <linux/pci.h>
  1501. +
  1502. +#include <asm/mach-ar71xx/ar71xx.h>
  1503. +#include <asm/mach-ar71xx/pci.h>
  1504. +
  1505. +#include "dev-pb9x-pci.h"
  1506. +
  1507. +static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = {
  1508. + {
  1509. + .slot = 0,
  1510. + .pin = 1,
  1511. + .irq = AR71XX_PCI_IRQ_DEV0,
  1512. + }
  1513. +};
  1514. +
  1515. +void __init pb9x_pci_init(void)
  1516. +{
  1517. + ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs);
  1518. +}
  1519. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.37/arch/mips/ar71xx/dev-pb9x-pci.h
  1520. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100
  1521. +++ linux-2.6.37/arch/mips/ar71xx/dev-pb9x-pci.h 2011-01-11 20:25:48.000000000 +0100
  1522. @@ -0,0 +1,22 @@
  1523. +/*
  1524. + * Atheros PB9x reference board PCI initialization
  1525. + *
  1526. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  1527. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1528. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1529. + *
  1530. + * This program is free software; you can redistribute it and/or modify it
  1531. + * under the terms of the GNU General Public License version 2 as published
  1532. + * by the Free Software Foundation.
  1533. + */
  1534. +
  1535. +#ifndef _AR71XX_DEV_PB9X_PCI_H
  1536. +#define _AR71XX_DEV_PB9X_PCI_H
  1537. +
  1538. +#if defined(CONFIG_AR71XX_DEV_PB9X_PCI)
  1539. +void pb9x_pci_init(void) __init;
  1540. +#else
  1541. +static inline void pb9x_pci_init(void) { }
  1542. +#endif
  1543. +
  1544. +#endif /* _AR71XX_DEV_PB9X_PCI_H */
  1545. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.37/arch/mips/ar71xx/dev-usb.c
  1546. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100
  1547. +++ linux-2.6.37/arch/mips/ar71xx/dev-usb.c 2011-01-11 20:25:48.000000000 +0100
  1548. @@ -0,0 +1,181 @@
  1549. +/*
  1550. + * Atheros AR71xx USB host device support
  1551. + *
  1552. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1553. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1554. + *
  1555. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1556. + *
  1557. + * This program is free software; you can redistribute it and/or modify it
  1558. + * under the terms of the GNU General Public License version 2 as published
  1559. + * by the Free Software Foundation.
  1560. + */
  1561. +
  1562. +#include <linux/kernel.h>
  1563. +#include <linux/init.h>
  1564. +#include <linux/delay.h>
  1565. +#include <linux/dma-mapping.h>
  1566. +#include <linux/platform_device.h>
  1567. +
  1568. +#include <asm/mach-ar71xx/ar71xx.h>
  1569. +#include <asm/mach-ar71xx/platform.h>
  1570. +
  1571. +#include "dev-usb.h"
  1572. +
  1573. +/*
  1574. + * OHCI (USB full speed host controller)
  1575. + */
  1576. +static struct resource ar71xx_ohci_resources[] = {
  1577. + [0] = {
  1578. + .start = AR71XX_OHCI_BASE,
  1579. + .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
  1580. + .flags = IORESOURCE_MEM,
  1581. + },
  1582. + [1] = {
  1583. + .start = AR71XX_MISC_IRQ_OHCI,
  1584. + .end = AR71XX_MISC_IRQ_OHCI,
  1585. + .flags = IORESOURCE_IRQ,
  1586. + },
  1587. +};
  1588. +
  1589. +static struct resource ar7240_ohci_resources[] = {
  1590. + [0] = {
  1591. + .start = AR7240_OHCI_BASE,
  1592. + .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
  1593. + .flags = IORESOURCE_MEM,
  1594. + },
  1595. + [1] = {
  1596. + .start = AR71XX_CPU_IRQ_USB,
  1597. + .end = AR71XX_CPU_IRQ_USB,
  1598. + .flags = IORESOURCE_IRQ,
  1599. + },
  1600. +};
  1601. +
  1602. +static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
  1603. +static struct platform_device ar71xx_ohci_device = {
  1604. + .name = "ar71xx-ohci",
  1605. + .id = -1,
  1606. + .resource = ar71xx_ohci_resources,
  1607. + .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
  1608. + .dev = {
  1609. + .dma_mask = &ar71xx_ohci_dmamask,
  1610. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1611. + },
  1612. +};
  1613. +
  1614. +/*
  1615. + * EHCI (USB full speed host controller)
  1616. + */
  1617. +static struct resource ar71xx_ehci_resources[] = {
  1618. + [0] = {
  1619. + .start = AR71XX_EHCI_BASE,
  1620. + .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
  1621. + .flags = IORESOURCE_MEM,
  1622. + },
  1623. + [1] = {
  1624. + .start = AR71XX_CPU_IRQ_USB,
  1625. + .end = AR71XX_CPU_IRQ_USB,
  1626. + .flags = IORESOURCE_IRQ,
  1627. + },
  1628. +};
  1629. +
  1630. +static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
  1631. +static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
  1632. +
  1633. +static struct platform_device ar71xx_ehci_device = {
  1634. + .name = "ar71xx-ehci",
  1635. + .id = -1,
  1636. + .resource = ar71xx_ehci_resources,
  1637. + .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
  1638. + .dev = {
  1639. + .dma_mask = &ar71xx_ehci_dmamask,
  1640. + .coherent_dma_mask = DMA_BIT_MASK(32),
  1641. + .platform_data = &ar71xx_ehci_data,
  1642. + },
  1643. +};
  1644. +
  1645. +#define AR71XX_USB_RESET_MASK \
  1646. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
  1647. + | RESET_MODULE_USB_OHCI_DLL)
  1648. +
  1649. +#define AR7240_USB_RESET_MASK \
  1650. + (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
  1651. +
  1652. +static void __init ar71xx_usb_setup(void)
  1653. +{
  1654. + ar71xx_device_stop(AR71XX_USB_RESET_MASK);
  1655. + mdelay(1000);
  1656. + ar71xx_device_start(AR71XX_USB_RESET_MASK);
  1657. +
  1658. + /* Turning on the Buff and Desc swap bits */
  1659. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
  1660. +
  1661. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1662. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
  1663. +
  1664. + mdelay(900);
  1665. +
  1666. + platform_device_register(&ar71xx_ohci_device);
  1667. + platform_device_register(&ar71xx_ehci_device);
  1668. +}
  1669. +
  1670. +static void __init ar7240_usb_setup(void)
  1671. +{
  1672. + ar71xx_device_stop(AR7240_USB_RESET_MASK);
  1673. + mdelay(1000);
  1674. + ar71xx_device_start(AR7240_USB_RESET_MASK);
  1675. +
  1676. + /* WAR for HW bug. Here it adjusts the duration between two SOFS */
  1677. + ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
  1678. +
  1679. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  1680. + ar71xx_ehci_data.is_ar91xx = 1;
  1681. + ar71xx_ehci_device.resource = ar7240_ohci_resources;
  1682. + ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1683. + platform_device_register(&ar71xx_ehci_device);
  1684. + } else {
  1685. + ar71xx_ohci_device.resource = ar7240_ohci_resources;
  1686. + ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
  1687. + platform_device_register(&ar71xx_ohci_device);
  1688. + }
  1689. +}
  1690. +
  1691. +static void __init ar91xx_usb_setup(void)
  1692. +{
  1693. + ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
  1694. + mdelay(10);
  1695. +
  1696. + ar71xx_device_start(RESET_MODULE_USB_HOST);
  1697. + mdelay(10);
  1698. +
  1699. + ar71xx_device_start(RESET_MODULE_USB_PHY);
  1700. + mdelay(10);
  1701. +
  1702. + ar71xx_ehci_data.is_ar91xx = 1;
  1703. + platform_device_register(&ar71xx_ehci_device);
  1704. +}
  1705. +
  1706. +void __init ar71xx_add_device_usb(void)
  1707. +{
  1708. + switch (ar71xx_soc) {
  1709. + case AR71XX_SOC_AR7240:
  1710. + case AR71XX_SOC_AR7241:
  1711. + case AR71XX_SOC_AR7242:
  1712. + ar7240_usb_setup();
  1713. + break;
  1714. +
  1715. + case AR71XX_SOC_AR7130:
  1716. + case AR71XX_SOC_AR7141:
  1717. + case AR71XX_SOC_AR7161:
  1718. + ar71xx_usb_setup();
  1719. + break;
  1720. +
  1721. + case AR71XX_SOC_AR9130:
  1722. + case AR71XX_SOC_AR9132:
  1723. + ar91xx_usb_setup();
  1724. + break;
  1725. +
  1726. + default:
  1727. + BUG();
  1728. + }
  1729. +}
  1730. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.37/arch/mips/ar71xx/dev-usb.h
  1731. --- linux-2.6.37.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100
  1732. +++ linux-2.6.37/arch/mips/ar71xx/dev-usb.h 2011-01-11 20:25:48.000000000 +0100
  1733. @@ -0,0 +1,17 @@
  1734. +/*
  1735. + * Atheros AR71xx USB host device support
  1736. + *
  1737. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1738. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1739. + *
  1740. + * This program is free software; you can redistribute it and/or modify it
  1741. + * under the terms of the GNU General Public License version 2 as published
  1742. + * by the Free Software Foundation.
  1743. + */
  1744. +
  1745. +#ifndef _AR71XX_DEV_USB_H
  1746. +#define _AR71XX_DEV_USB_H
  1747. +
  1748. +void ar71xx_add_device_usb(void) __init;
  1749. +
  1750. +#endif /* _AR71XX_DEV_USB_H */
  1751. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/devices.c linux-2.6.37/arch/mips/ar71xx/devices.c
  1752. --- linux-2.6.37.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100
  1753. +++ linux-2.6.37/arch/mips/ar71xx/devices.c 2011-01-11 20:25:48.000000000 +0100
  1754. @@ -0,0 +1,575 @@
  1755. +/*
  1756. + * Atheros AR71xx SoC platform devices
  1757. + *
  1758. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  1759. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  1760. + *
  1761. + * Parts of this file are based on Atheros' 2.6.15 BSP
  1762. + *
  1763. + * This program is free software; you can redistribute it and/or modify it
  1764. + * under the terms of the GNU General Public License version 2 as published
  1765. + * by the Free Software Foundation.
  1766. + */
  1767. +
  1768. +#include <linux/kernel.h>
  1769. +#include <linux/init.h>
  1770. +#include <linux/delay.h>
  1771. +#include <linux/etherdevice.h>
  1772. +#include <linux/platform_device.h>
  1773. +#include <linux/serial_8250.h>
  1774. +
  1775. +#include <asm/mach-ar71xx/ar71xx.h>
  1776. +
  1777. +#include "devices.h"
  1778. +
  1779. +static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
  1780. +
  1781. +static struct resource ar71xx_uart_resources[] = {
  1782. + {
  1783. + .start = AR71XX_UART_BASE,
  1784. + .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
  1785. + .flags = IORESOURCE_MEM,
  1786. + },
  1787. +};
  1788. +
  1789. +#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
  1790. +static struct plat_serial8250_port ar71xx_uart_data[] = {
  1791. + {
  1792. + .mapbase = AR71XX_UART_BASE,
  1793. + .irq = AR71XX_MISC_IRQ_UART,
  1794. + .flags = AR71XX_UART_FLAGS,
  1795. + .iotype = UPIO_MEM32,
  1796. + .regshift = 2,
  1797. + }, {
  1798. + /* terminating entry */
  1799. + }
  1800. +};
  1801. +
  1802. +static struct platform_device ar71xx_uart_device = {
  1803. + .name = "serial8250",
  1804. + .id = PLAT8250_DEV_PLATFORM,
  1805. + .resource = ar71xx_uart_resources,
  1806. + .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
  1807. + .dev = {
  1808. + .platform_data = ar71xx_uart_data
  1809. + },
  1810. +};
  1811. +
  1812. +void __init ar71xx_add_device_uart(void)
  1813. +{
  1814. + ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
  1815. + platform_device_register(&ar71xx_uart_device);
  1816. +}
  1817. +
  1818. +static struct resource ar71xx_mdio_resources[] = {
  1819. + {
  1820. + .name = "mdio_base",
  1821. + .flags = IORESOURCE_MEM,
  1822. + .start = AR71XX_GE0_BASE,
  1823. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1824. + }
  1825. +};
  1826. +
  1827. +static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
  1828. +
  1829. +struct platform_device ar71xx_mdio_device = {
  1830. + .name = "ag71xx-mdio",
  1831. + .id = -1,
  1832. + .resource = ar71xx_mdio_resources,
  1833. + .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
  1834. + .dev = {
  1835. + .platform_data = &ar71xx_mdio_data,
  1836. + },
  1837. +};
  1838. +
  1839. +void __init ar71xx_add_device_mdio(u32 phy_mask)
  1840. +{
  1841. + switch (ar71xx_soc) {
  1842. + case AR71XX_SOC_AR7240:
  1843. + case AR71XX_SOC_AR7241:
  1844. + case AR71XX_SOC_AR7242:
  1845. + ar71xx_mdio_data.is_ar7240 = 1;
  1846. + break;
  1847. + default:
  1848. + break;
  1849. + }
  1850. +
  1851. + ar71xx_mdio_data.phy_mask = phy_mask;
  1852. +
  1853. + platform_device_register(&ar71xx_mdio_device);
  1854. +}
  1855. +
  1856. +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
  1857. +{
  1858. + void __iomem *base;
  1859. + u32 t;
  1860. +
  1861. + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
  1862. +
  1863. + t = __raw_readl(base + cfg_reg);
  1864. + t &= ~(3 << shift);
  1865. + t |= (2 << shift);
  1866. + __raw_writel(t, base + cfg_reg);
  1867. + udelay(100);
  1868. +
  1869. + __raw_writel(pll_val, base + pll_reg);
  1870. +
  1871. + t |= (3 << shift);
  1872. + __raw_writel(t, base + cfg_reg);
  1873. + udelay(100);
  1874. +
  1875. + t &= ~(3 << shift);
  1876. + __raw_writel(t, base + cfg_reg);
  1877. + udelay(100);
  1878. +
  1879. + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
  1880. + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
  1881. +
  1882. + iounmap(base);
  1883. +}
  1884. +
  1885. +struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  1886. +struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  1887. +
  1888. +static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
  1889. +{
  1890. + struct ar71xx_eth_pll_data *pll_data;
  1891. + u32 pll_val;
  1892. +
  1893. + switch (mac) {
  1894. + case 0:
  1895. + pll_data = &ar71xx_eth0_pll_data;
  1896. + break;
  1897. + case 1:
  1898. + pll_data = &ar71xx_eth1_pll_data;
  1899. + break;
  1900. + default:
  1901. + BUG();
  1902. + }
  1903. +
  1904. + switch (speed) {
  1905. + case SPEED_10:
  1906. + pll_val = pll_data->pll_10;
  1907. + break;
  1908. + case SPEED_100:
  1909. + pll_val = pll_data->pll_100;
  1910. + break;
  1911. + case SPEED_1000:
  1912. + pll_val = pll_data->pll_1000;
  1913. + break;
  1914. + default:
  1915. + BUG();
  1916. + }
  1917. +
  1918. + return pll_val;
  1919. +}
  1920. +
  1921. +static void ar71xx_set_pll_ge0(int speed)
  1922. +{
  1923. + u32 val = ar71xx_get_eth_pll(0, speed);
  1924. +
  1925. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
  1926. + val, AR71XX_ETH0_PLL_SHIFT);
  1927. +}
  1928. +
  1929. +static void ar71xx_set_pll_ge1(int speed)
  1930. +{
  1931. + u32 val = ar71xx_get_eth_pll(1, speed);
  1932. +
  1933. + ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
  1934. + val, AR71XX_ETH1_PLL_SHIFT);
  1935. +}
  1936. +
  1937. +static void ar724x_set_pll_ge0(int speed)
  1938. +{
  1939. + /* TODO */
  1940. +}
  1941. +
  1942. +static void ar724x_set_pll_ge1(int speed)
  1943. +{
  1944. + /* TODO */
  1945. +}
  1946. +
  1947. +static void ar91xx_set_pll_ge0(int speed)
  1948. +{
  1949. + u32 val = ar71xx_get_eth_pll(0, speed);
  1950. +
  1951. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
  1952. + val, AR91XX_ETH0_PLL_SHIFT);
  1953. +}
  1954. +
  1955. +static void ar91xx_set_pll_ge1(int speed)
  1956. +{
  1957. + u32 val = ar71xx_get_eth_pll(1, speed);
  1958. +
  1959. + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
  1960. + val, AR91XX_ETH1_PLL_SHIFT);
  1961. +}
  1962. +
  1963. +static void ar71xx_ddr_flush_ge0(void)
  1964. +{
  1965. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
  1966. +}
  1967. +
  1968. +static void ar71xx_ddr_flush_ge1(void)
  1969. +{
  1970. + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
  1971. +}
  1972. +
  1973. +static void ar724x_ddr_flush_ge0(void)
  1974. +{
  1975. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
  1976. +}
  1977. +
  1978. +static void ar724x_ddr_flush_ge1(void)
  1979. +{
  1980. + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
  1981. +}
  1982. +
  1983. +static void ar91xx_ddr_flush_ge0(void)
  1984. +{
  1985. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
  1986. +}
  1987. +
  1988. +static void ar91xx_ddr_flush_ge1(void)
  1989. +{
  1990. + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
  1991. +}
  1992. +
  1993. +static struct resource ar71xx_eth0_resources[] = {
  1994. + {
  1995. + .name = "mac_base",
  1996. + .flags = IORESOURCE_MEM,
  1997. + .start = AR71XX_GE0_BASE,
  1998. + .end = AR71XX_GE0_BASE + 0x200 - 1,
  1999. + }, {
  2000. + .name = "mii_ctrl",
  2001. + .flags = IORESOURCE_MEM,
  2002. + .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
  2003. + .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
  2004. + }, {
  2005. + .name = "mac_irq",
  2006. + .flags = IORESOURCE_IRQ,
  2007. + .start = AR71XX_CPU_IRQ_GE0,
  2008. + .end = AR71XX_CPU_IRQ_GE0,
  2009. + },
  2010. +};
  2011. +
  2012. +struct ag71xx_platform_data ar71xx_eth0_data = {
  2013. + .reset_bit = RESET_MODULE_GE0_MAC,
  2014. +};
  2015. +
  2016. +struct platform_device ar71xx_eth0_device = {
  2017. + .name = "ag71xx",
  2018. + .id = 0,
  2019. + .resource = ar71xx_eth0_resources,
  2020. + .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
  2021. + .dev = {
  2022. + .platform_data = &ar71xx_eth0_data,
  2023. + },
  2024. +};
  2025. +
  2026. +static struct resource ar71xx_eth1_resources[] = {
  2027. + {
  2028. + .name = "mac_base",
  2029. + .flags = IORESOURCE_MEM,
  2030. + .start = AR71XX_GE1_BASE,
  2031. + .end = AR71XX_GE1_BASE + 0x200 - 1,
  2032. + }, {
  2033. + .name = "mii_ctrl",
  2034. + .flags = IORESOURCE_MEM,
  2035. + .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
  2036. + .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
  2037. + }, {
  2038. + .name = "mac_irq",
  2039. + .flags = IORESOURCE_IRQ,
  2040. + .start = AR71XX_CPU_IRQ_GE1,
  2041. + .end = AR71XX_CPU_IRQ_GE1,
  2042. + },
  2043. +};
  2044. +
  2045. +struct ag71xx_platform_data ar71xx_eth1_data = {
  2046. + .reset_bit = RESET_MODULE_GE1_MAC,
  2047. +};
  2048. +
  2049. +struct platform_device ar71xx_eth1_device = {
  2050. + .name = "ag71xx",
  2051. + .id = 1,
  2052. + .resource = ar71xx_eth1_resources,
  2053. + .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
  2054. + .dev = {
  2055. + .platform_data = &ar71xx_eth1_data,
  2056. + },
  2057. +};
  2058. +
  2059. +#define AR71XX_PLL_VAL_1000 0x00110000
  2060. +#define AR71XX_PLL_VAL_100 0x00001099
  2061. +#define AR71XX_PLL_VAL_10 0x00991099
  2062. +
  2063. +#define AR724X_PLL_VAL_1000 0x00110000
  2064. +#define AR724X_PLL_VAL_100 0x00001099
  2065. +#define AR724X_PLL_VAL_10 0x00991099
  2066. +
  2067. +#define AR91XX_PLL_VAL_1000 0x1a000000
  2068. +#define AR91XX_PLL_VAL_100 0x13000a44
  2069. +#define AR91XX_PLL_VAL_10 0x00441099
  2070. +
  2071. +static void __init ar71xx_init_eth_pll_data(unsigned int id)
  2072. +{
  2073. + struct ar71xx_eth_pll_data *pll_data;
  2074. + u32 pll_10, pll_100, pll_1000;
  2075. +
  2076. + switch (id) {
  2077. + case 0:
  2078. + pll_data = &ar71xx_eth0_pll_data;
  2079. + break;
  2080. + case 1:
  2081. + pll_data = &ar71xx_eth1_pll_data;
  2082. + break;
  2083. + default:
  2084. + BUG();
  2085. + }
  2086. +
  2087. + switch (ar71xx_soc) {
  2088. + case AR71XX_SOC_AR7130:
  2089. + case AR71XX_SOC_AR7141:
  2090. + case AR71XX_SOC_AR7161:
  2091. + pll_10 = AR71XX_PLL_VAL_10;
  2092. + pll_100 = AR71XX_PLL_VAL_100;
  2093. + pll_1000 = AR71XX_PLL_VAL_1000;
  2094. + break;
  2095. +
  2096. + case AR71XX_SOC_AR7240:
  2097. + case AR71XX_SOC_AR7241:
  2098. + case AR71XX_SOC_AR7242:
  2099. + pll_10 = AR724X_PLL_VAL_10;
  2100. + pll_100 = AR724X_PLL_VAL_100;
  2101. + pll_1000 = AR724X_PLL_VAL_1000;
  2102. + break;
  2103. +
  2104. + case AR71XX_SOC_AR9130:
  2105. + case AR71XX_SOC_AR9132:
  2106. + pll_10 = AR91XX_PLL_VAL_10;
  2107. + pll_100 = AR91XX_PLL_VAL_100;
  2108. + pll_1000 = AR91XX_PLL_VAL_1000;
  2109. + break;
  2110. + default:
  2111. + BUG();
  2112. + }
  2113. +
  2114. + if (!pll_data->pll_10)
  2115. + pll_data->pll_10 = pll_10;
  2116. +
  2117. + if (!pll_data->pll_100)
  2118. + pll_data->pll_100 = pll_100;
  2119. +
  2120. + if (!pll_data->pll_1000)
  2121. + pll_data->pll_1000 = pll_1000;
  2122. +}
  2123. +
  2124. +static int ar71xx_eth_instance __initdata;
  2125. +void __init ar71xx_add_device_eth(unsigned int id)
  2126. +{
  2127. + struct platform_device *pdev;
  2128. + struct ag71xx_platform_data *pdata;
  2129. +
  2130. + ar71xx_init_eth_pll_data(id);
  2131. +
  2132. + switch (id) {
  2133. + case 0:
  2134. + switch (ar71xx_eth0_data.phy_if_mode) {
  2135. + case PHY_INTERFACE_MODE_MII:
  2136. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
  2137. + break;
  2138. + case PHY_INTERFACE_MODE_GMII:
  2139. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
  2140. + break;
  2141. + case PHY_INTERFACE_MODE_RGMII:
  2142. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
  2143. + break;
  2144. + case PHY_INTERFACE_MODE_RMII:
  2145. + ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
  2146. + break;
  2147. + default:
  2148. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2149. + "for eth0\n");
  2150. + return;
  2151. + }
  2152. + pdev = &ar71xx_eth0_device;
  2153. + break;
  2154. + case 1:
  2155. + switch (ar71xx_eth1_data.phy_if_mode) {
  2156. + case PHY_INTERFACE_MODE_RMII:
  2157. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
  2158. + break;
  2159. + case PHY_INTERFACE_MODE_RGMII:
  2160. + ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
  2161. + break;
  2162. + default:
  2163. + printk(KERN_ERR "ar71xx: invalid PHY interface mode "
  2164. + "for eth1\n");
  2165. + return;
  2166. + }
  2167. + pdev = &ar71xx_eth1_device;
  2168. + break;
  2169. + default:
  2170. + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
  2171. + return;
  2172. + }
  2173. +
  2174. + pdata = pdev->dev.platform_data;
  2175. +
  2176. + switch (ar71xx_soc) {
  2177. + case AR71XX_SOC_AR7130:
  2178. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2179. + : ar71xx_ddr_flush_ge0;
  2180. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2181. + : ar71xx_set_pll_ge0;
  2182. + break;
  2183. +
  2184. + case AR71XX_SOC_AR7141:
  2185. + case AR71XX_SOC_AR7161:
  2186. + pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
  2187. + : ar71xx_ddr_flush_ge0;
  2188. + pdata->set_pll = id ? ar71xx_set_pll_ge1
  2189. + : ar71xx_set_pll_ge0;
  2190. + pdata->has_gbit = 1;
  2191. + break;
  2192. +
  2193. + case AR71XX_SOC_AR7241:
  2194. + case AR71XX_SOC_AR7242:
  2195. + ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
  2196. + ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
  2197. + /* fall through */
  2198. + case AR71XX_SOC_AR7240:
  2199. + pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
  2200. + : ar724x_ddr_flush_ge0;
  2201. + pdata->set_pll = id ? ar724x_set_pll_ge1
  2202. + : ar724x_set_pll_ge0;
  2203. + pdata->is_ar724x = 1;
  2204. + break;
  2205. +
  2206. + case AR71XX_SOC_AR9130:
  2207. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2208. + : ar91xx_ddr_flush_ge0;
  2209. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2210. + : ar91xx_set_pll_ge0;
  2211. + pdata->is_ar91xx = 1;
  2212. + break;
  2213. +
  2214. + case AR71XX_SOC_AR9132:
  2215. + pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
  2216. + : ar91xx_ddr_flush_ge0;
  2217. + pdata->set_pll = id ? ar91xx_set_pll_ge1
  2218. + : ar91xx_set_pll_ge0;
  2219. + pdata->is_ar91xx = 1;
  2220. + pdata->has_gbit = 1;
  2221. + break;
  2222. +
  2223. + default:
  2224. + BUG();
  2225. + }
  2226. +
  2227. + switch (pdata->phy_if_mode) {
  2228. + case PHY_INTERFACE_MODE_GMII:
  2229. + case PHY_INTERFACE_MODE_RGMII:
  2230. + if (!pdata->has_gbit) {
  2231. + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
  2232. + id);
  2233. + return;
  2234. + }
  2235. + /* fallthrough */
  2236. + default:
  2237. + break;
  2238. + }
  2239. +
  2240. + if (is_valid_ether_addr(ar71xx_mac_base)) {
  2241. + memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
  2242. + pdata->mac_addr[5] += ar71xx_eth_instance;
  2243. + } else {
  2244. + random_ether_addr(pdata->mac_addr);
  2245. + printk(KERN_DEBUG
  2246. + "ar71xx: using random MAC address for eth%d\n",
  2247. + ar71xx_eth_instance);
  2248. + }
  2249. +
  2250. + if (pdata->mii_bus_dev == NULL)
  2251. + pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
  2252. +
  2253. + /* Reset the device */
  2254. + ar71xx_device_stop(pdata->reset_bit);
  2255. + mdelay(100);
  2256. +
  2257. + ar71xx_device_start(pdata->reset_bit);
  2258. + mdelay(100);
  2259. +
  2260. + platform_device_register(pdev);
  2261. + ar71xx_eth_instance++;
  2262. +}
  2263. +
  2264. +static struct resource ar71xx_spi_resources[] = {
  2265. + [0] = {
  2266. + .start = AR71XX_SPI_BASE,
  2267. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  2268. + .flags = IORESOURCE_MEM,
  2269. + },
  2270. +};
  2271. +
  2272. +static struct platform_device ar71xx_spi_device = {
  2273. + .name = "ar71xx-spi",
  2274. + .id = -1,
  2275. + .resource = ar71xx_spi_resources,
  2276. + .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
  2277. +};
  2278. +
  2279. +void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2280. + struct spi_board_info const *info,
  2281. + unsigned n)
  2282. +{
  2283. + spi_register_board_info(info, n);
  2284. + ar71xx_spi_device.dev.platform_data = pdata;
  2285. + platform_device_register(&ar71xx_spi_device);
  2286. +}
  2287. +
  2288. +void __init ar71xx_add_device_wdt(void)
  2289. +{
  2290. + platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
  2291. +}
  2292. +
  2293. +void __init ar71xx_set_mac_base(unsigned char *mac)
  2294. +{
  2295. + memcpy(ar71xx_mac_base, mac, ETH_ALEN);
  2296. +}
  2297. +
  2298. +void __init ar71xx_parse_mac_addr(char *mac_str)
  2299. +{
  2300. + u8 tmp[ETH_ALEN];
  2301. + int t;
  2302. +
  2303. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  2304. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2305. +
  2306. + if (t != ETH_ALEN)
  2307. + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
  2308. + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
  2309. +
  2310. + if (t == ETH_ALEN)
  2311. + ar71xx_set_mac_base(tmp);
  2312. + else
  2313. + printk(KERN_DEBUG "ar71xx: failed to parse mac address "
  2314. + "\"%s\"\n", mac_str);
  2315. +}
  2316. +
  2317. +static int __init ar71xx_ethaddr_setup(char *str)
  2318. +{
  2319. + ar71xx_parse_mac_addr(str);
  2320. + return 1;
  2321. +}
  2322. +__setup("ethaddr=", ar71xx_ethaddr_setup);
  2323. +
  2324. +static int __init ar71xx_kmac_setup(char *str)
  2325. +{
  2326. + ar71xx_parse_mac_addr(str);
  2327. + return 1;
  2328. +}
  2329. +__setup("kmac=", ar71xx_kmac_setup);
  2330. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/devices.h linux-2.6.37/arch/mips/ar71xx/devices.h
  2331. --- linux-2.6.37.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100
  2332. +++ linux-2.6.37/arch/mips/ar71xx/devices.h 2011-01-11 20:25:48.000000000 +0100
  2333. @@ -0,0 +1,48 @@
  2334. +/*
  2335. + * Atheros AR71xx SoC device definitions
  2336. + *
  2337. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2338. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2339. + *
  2340. + * This program is free software; you can redistribute it and/or modify it
  2341. + * under the terms of the GNU General Public License version 2 as published
  2342. + * by the Free Software Foundation.
  2343. + */
  2344. +
  2345. +#ifndef __AR71XX_DEVICES_H
  2346. +#define __AR71XX_DEVICES_H
  2347. +
  2348. +#include <asm/mach-ar71xx/platform.h>
  2349. +
  2350. +struct platform_device;
  2351. +
  2352. +void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
  2353. + struct spi_board_info const *info,
  2354. + unsigned n) __init;
  2355. +
  2356. +void ar71xx_set_mac_base(unsigned char *mac) __init;
  2357. +void ar71xx_parse_mac_addr(char *mac_str) __init;
  2358. +
  2359. +struct ar71xx_eth_pll_data {
  2360. + u32 pll_10;
  2361. + u32 pll_100;
  2362. + u32 pll_1000;
  2363. +};
  2364. +
  2365. +extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
  2366. +extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
  2367. +
  2368. +extern struct ag71xx_platform_data ar71xx_eth0_data;
  2369. +extern struct ag71xx_platform_data ar71xx_eth1_data;
  2370. +extern struct platform_device ar71xx_eth0_device;
  2371. +extern struct platform_device ar71xx_eth1_device;
  2372. +void ar71xx_add_device_eth(unsigned int id) __init;
  2373. +
  2374. +extern struct platform_device ar71xx_mdio_device;
  2375. +void ar71xx_add_device_mdio(u32 phy_mask) __init;
  2376. +
  2377. +void ar71xx_add_device_uart(void) __init;
  2378. +
  2379. +void ar71xx_add_device_wdt(void) __init;
  2380. +
  2381. +#endif /* __AR71XX_DEVICES_H */
  2382. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/early_printk.c linux-2.6.37/arch/mips/ar71xx/early_printk.c
  2383. --- linux-2.6.37.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100
  2384. +++ linux-2.6.37/arch/mips/ar71xx/early_printk.c 2011-01-11 20:25:48.000000000 +0100
  2385. @@ -0,0 +1,30 @@
  2386. +/*
  2387. + * Atheros AR71xx SoC early printk support
  2388. + *
  2389. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  2390. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2391. + *
  2392. + * This program is free software; you can redistribute it and/or modify it
  2393. + * under the terms of the GNU General Public License version 2 as published
  2394. + * by the Free Software Foundation.
  2395. + */
  2396. +
  2397. +#include <linux/io.h>
  2398. +#include <linux/serial_reg.h>
  2399. +#include <asm/addrspace.h>
  2400. +
  2401. +#include <asm/mach-ar71xx/ar71xx.h>
  2402. +
  2403. +#define UART_READ(r) \
  2404. + __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r)))
  2405. +
  2406. +#define UART_WRITE(r, v) \
  2407. + __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r)))
  2408. +
  2409. +void prom_putchar(unsigned char ch)
  2410. +{
  2411. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2412. + UART_WRITE(UART_TX, ch);
  2413. + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
  2414. +}
  2415. +
  2416. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/gpio.c linux-2.6.37/arch/mips/ar71xx/gpio.c
  2417. --- linux-2.6.37.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
  2418. +++ linux-2.6.37/arch/mips/ar71xx/gpio.c 2011-01-11 20:25:48.000000000 +0100
  2419. @@ -0,0 +1,182 @@
  2420. +/*
  2421. + * Atheros AR71xx SoC GPIO API support
  2422. + *
  2423. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2424. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2425. + *
  2426. + * This program is free software; you can redistribute it and/or modify it
  2427. + * under the terms of the GNU General Public License version 2 as published
  2428. + * by the Free Software Foundation.
  2429. + */
  2430. +
  2431. +#include <linux/kernel.h>
  2432. +#include <linux/init.h>
  2433. +#include <linux/module.h>
  2434. +#include <linux/types.h>
  2435. +#include <linux/spinlock.h>
  2436. +#include <linux/io.h>
  2437. +#include <linux/ioport.h>
  2438. +#include <linux/gpio.h>
  2439. +
  2440. +#include <asm/mach-ar71xx/ar71xx.h>
  2441. +
  2442. +static DEFINE_SPINLOCK(ar71xx_gpio_lock);
  2443. +
  2444. +unsigned long ar71xx_gpio_count;
  2445. +EXPORT_SYMBOL(ar71xx_gpio_count);
  2446. +
  2447. +void __ar71xx_gpio_set_value(unsigned gpio, int value)
  2448. +{
  2449. + void __iomem *base = ar71xx_gpio_base;
  2450. +
  2451. + if (value)
  2452. + __raw_writel(1 << gpio, base + GPIO_REG_SET);
  2453. + else
  2454. + __raw_writel(1 << gpio, base + GPIO_REG_CLEAR);
  2455. +}
  2456. +EXPORT_SYMBOL(__ar71xx_gpio_set_value);
  2457. +
  2458. +int __ar71xx_gpio_get_value(unsigned gpio)
  2459. +{
  2460. + return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1;
  2461. +}
  2462. +EXPORT_SYMBOL(__ar71xx_gpio_get_value);
  2463. +
  2464. +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  2465. +{
  2466. + return __ar71xx_gpio_get_value(offset);
  2467. +}
  2468. +
  2469. +static void ar71xx_gpio_set_value(struct gpio_chip *chip,
  2470. + unsigned offset, int value)
  2471. +{
  2472. + __ar71xx_gpio_set_value(offset, value);
  2473. +}
  2474. +
  2475. +static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
  2476. + unsigned offset)
  2477. +{
  2478. + void __iomem *base = ar71xx_gpio_base;
  2479. + unsigned long flags;
  2480. +
  2481. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2482. +
  2483. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset),
  2484. + base + GPIO_REG_OE);
  2485. +
  2486. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2487. +
  2488. + return 0;
  2489. +}
  2490. +
  2491. +static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
  2492. + unsigned offset, int value)
  2493. +{
  2494. + void __iomem *base = ar71xx_gpio_base;
  2495. + unsigned long flags;
  2496. +
  2497. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2498. +
  2499. + if (value)
  2500. + __raw_writel(1 << offset, base + GPIO_REG_SET);
  2501. + else
  2502. + __raw_writel(1 << offset, base + GPIO_REG_CLEAR);
  2503. +
  2504. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset),
  2505. + base + GPIO_REG_OE);
  2506. +
  2507. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2508. +
  2509. + return 0;
  2510. +}
  2511. +
  2512. +static struct gpio_chip ar71xx_gpio_chip = {
  2513. + .label = "ar71xx",
  2514. + .get = ar71xx_gpio_get_value,
  2515. + .set = ar71xx_gpio_set_value,
  2516. + .direction_input = ar71xx_gpio_direction_input,
  2517. + .direction_output = ar71xx_gpio_direction_output,
  2518. + .base = 0,
  2519. + .ngpio = AR71XX_GPIO_COUNT,
  2520. +};
  2521. +
  2522. +void ar71xx_gpio_function_enable(u32 mask)
  2523. +{
  2524. + void __iomem *base = ar71xx_gpio_base;
  2525. + unsigned long flags;
  2526. +
  2527. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2528. +
  2529. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask,
  2530. + base + GPIO_REG_FUNC);
  2531. + /* flush write */
  2532. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2533. +
  2534. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2535. +}
  2536. +
  2537. +void ar71xx_gpio_function_disable(u32 mask)
  2538. +{
  2539. + void __iomem *base = ar71xx_gpio_base;
  2540. + unsigned long flags;
  2541. +
  2542. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2543. +
  2544. + __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask,
  2545. + base + GPIO_REG_FUNC);
  2546. + /* flush write */
  2547. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2548. +
  2549. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2550. +}
  2551. +
  2552. +void ar71xx_gpio_function_setup(u32 set, u32 clear)
  2553. +{
  2554. + void __iomem *base = ar71xx_gpio_base;
  2555. + unsigned long flags;
  2556. +
  2557. + spin_lock_irqsave(&ar71xx_gpio_lock, flags);
  2558. +
  2559. + __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set,
  2560. + base + GPIO_REG_FUNC);
  2561. + /* flush write */
  2562. + (void) __raw_readl(base + GPIO_REG_FUNC);
  2563. +
  2564. + spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
  2565. +}
  2566. +EXPORT_SYMBOL(ar71xx_gpio_function_setup);
  2567. +
  2568. +void __init ar71xx_gpio_init(void)
  2569. +{
  2570. + int err;
  2571. +
  2572. + if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
  2573. + "AR71xx GPIO controller"))
  2574. + panic("cannot allocate AR71xx GPIO registers page");
  2575. +
  2576. + switch (ar71xx_soc) {
  2577. + case AR71XX_SOC_AR7130:
  2578. + case AR71XX_SOC_AR7141:
  2579. + case AR71XX_SOC_AR7161:
  2580. + ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
  2581. + break;
  2582. +
  2583. + case AR71XX_SOC_AR7240:
  2584. + case AR71XX_SOC_AR7241:
  2585. + case AR71XX_SOC_AR7242:
  2586. + ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT;
  2587. + break;
  2588. +
  2589. + case AR71XX_SOC_AR9130:
  2590. + case AR71XX_SOC_AR9132:
  2591. + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
  2592. + break;
  2593. +
  2594. + default:
  2595. + BUG();
  2596. + }
  2597. +
  2598. + err = gpiochip_add(&ar71xx_gpio_chip);
  2599. + if (err)
  2600. + panic("cannot add AR71xx GPIO chip, error=%d", err);
  2601. +}
  2602. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/irq.c linux-2.6.37/arch/mips/ar71xx/irq.c
  2603. --- linux-2.6.37.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100
  2604. +++ linux-2.6.37/arch/mips/ar71xx/irq.c 2011-01-11 20:25:48.000000000 +0100
  2605. @@ -0,0 +1,295 @@
  2606. +/*
  2607. + * Atheros AR71xx SoC specific interrupt handling
  2608. + *
  2609. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  2610. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  2611. + *
  2612. + * Parts of this file are based on Atheros' 2.6.15 BSP
  2613. + *
  2614. + * This program is free software; you can redistribute it and/or modify it
  2615. + * under the terms of the GNU General Public License version 2 as published
  2616. + * by the Free Software Foundation.
  2617. + */
  2618. +
  2619. +#include <linux/kernel.h>
  2620. +#include <linux/init.h>
  2621. +#include <linux/interrupt.h>
  2622. +#include <linux/irq.h>
  2623. +
  2624. +#include <asm/irq_cpu.h>
  2625. +#include <asm/mipsregs.h>
  2626. +
  2627. +#include <asm/mach-ar71xx/ar71xx.h>
  2628. +
  2629. +static int ip2_flush_reg;
  2630. +
  2631. +static void ar71xx_gpio_irq_dispatch(void)
  2632. +{
  2633. + void __iomem *base = ar71xx_gpio_base;
  2634. + u32 pending;
  2635. +
  2636. + pending = __raw_readl(base + GPIO_REG_INT_PENDING) &
  2637. + __raw_readl(base + GPIO_REG_INT_ENABLE);
  2638. +
  2639. + if (pending)
  2640. + do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
  2641. + else
  2642. + spurious_interrupt();
  2643. +}
  2644. +
  2645. +static void ar71xx_gpio_irq_unmask(unsigned int irq)
  2646. +{
  2647. + void __iomem *base = ar71xx_gpio_base;
  2648. + u32 t;
  2649. +
  2650. + irq -= AR71XX_GPIO_IRQ_BASE;
  2651. +
  2652. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2653. + __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE);
  2654. +
  2655. + /* flush write */
  2656. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2657. +}
  2658. +
  2659. +static void ar71xx_gpio_irq_mask(unsigned int irq)
  2660. +{
  2661. + void __iomem *base = ar71xx_gpio_base;
  2662. + u32 t;
  2663. +
  2664. + irq -= AR71XX_GPIO_IRQ_BASE;
  2665. +
  2666. + t = __raw_readl(base + GPIO_REG_INT_ENABLE);
  2667. + __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE);
  2668. +
  2669. + /* flush write */
  2670. + (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
  2671. +}
  2672. +
  2673. +#if 0
  2674. +static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
  2675. +{
  2676. + /* TODO: implement */
  2677. + return 0;
  2678. +}
  2679. +#else
  2680. +#define ar71xx_gpio_irq_set_type NULL
  2681. +#endif
  2682. +
  2683. +static struct irq_chip ar71xx_gpio_irq_chip = {
  2684. + .name = "AR71XX GPIO",
  2685. + .unmask = ar71xx_gpio_irq_unmask,
  2686. + .mask = ar71xx_gpio_irq_mask,
  2687. + .mask_ack = ar71xx_gpio_irq_mask,
  2688. + .set_type = ar71xx_gpio_irq_set_type,
  2689. +};
  2690. +
  2691. +static struct irqaction ar71xx_gpio_irqaction = {
  2692. + .handler = no_action,
  2693. + .name = "cascade [AR71XX GPIO]",
  2694. +};
  2695. +
  2696. +#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED)
  2697. +#define GPIO_INT_ALL 0xffff
  2698. +
  2699. +static void __init ar71xx_gpio_irq_init(void)
  2700. +{
  2701. + void __iomem *base = ar71xx_gpio_base;
  2702. + int i;
  2703. +
  2704. + __raw_writel(0, base + GPIO_REG_INT_ENABLE);
  2705. + __raw_writel(0, base + GPIO_REG_INT_PENDING);
  2706. +
  2707. + /* setup type of all GPIO interrupts to level sensitive */
  2708. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE);
  2709. +
  2710. + /* setup polarity of all GPIO interrupts to active high */
  2711. + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY);
  2712. +
  2713. + for (i = AR71XX_GPIO_IRQ_BASE;
  2714. + i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) {
  2715. + irq_desc[i].status = GPIO_IRQ_INIT_STATUS;
  2716. + set_irq_chip_and_handler(i, &ar71xx_gpio_irq_chip,
  2717. + handle_level_irq);
  2718. + }
  2719. +
  2720. + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
  2721. +}
  2722. +
  2723. +static void ar71xx_misc_irq_dispatch(void)
  2724. +{
  2725. + u32 pending;
  2726. +
  2727. + pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
  2728. + & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
  2729. +
  2730. + if (pending & MISC_INT_UART)
  2731. + do_IRQ(AR71XX_MISC_IRQ_UART);
  2732. +
  2733. + else if (pending & MISC_INT_DMA)
  2734. + do_IRQ(AR71XX_MISC_IRQ_DMA);
  2735. +
  2736. + else if (pending & MISC_INT_PERFC)
  2737. + do_IRQ(AR71XX_MISC_IRQ_PERFC);
  2738. +
  2739. + else if (pending & MISC_INT_TIMER)
  2740. + do_IRQ(AR71XX_MISC_IRQ_TIMER);
  2741. +
  2742. + else if (pending & MISC_INT_OHCI)
  2743. + do_IRQ(AR71XX_MISC_IRQ_OHCI);
  2744. +
  2745. + else if (pending & MISC_INT_ERROR)
  2746. + do_IRQ(AR71XX_MISC_IRQ_ERROR);
  2747. +
  2748. + else if (pending & MISC_INT_GPIO)
  2749. + ar71xx_gpio_irq_dispatch();
  2750. +
  2751. + else if (pending & MISC_INT_WDOG)
  2752. + do_IRQ(AR71XX_MISC_IRQ_WDOG);
  2753. +
  2754. + else
  2755. + spurious_interrupt();
  2756. +}
  2757. +
  2758. +static void ar71xx_misc_irq_unmask(unsigned int irq)
  2759. +{
  2760. + void __iomem *base = ar71xx_reset_base;
  2761. + u32 t;
  2762. +
  2763. + irq -= AR71XX_MISC_IRQ_BASE;
  2764. +
  2765. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2766. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2767. +
  2768. + /* flush write */
  2769. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2770. +}
  2771. +
  2772. +static void ar71xx_misc_irq_mask(unsigned int irq)
  2773. +{
  2774. + void __iomem *base = ar71xx_reset_base;
  2775. + u32 t;
  2776. +
  2777. + irq -= AR71XX_MISC_IRQ_BASE;
  2778. +
  2779. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2780. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2781. +
  2782. + /* flush write */
  2783. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2784. +}
  2785. +
  2786. +static void ar724x_misc_irq_ack(unsigned int irq)
  2787. +{
  2788. + void __iomem *base = ar71xx_reset_base;
  2789. + u32 t;
  2790. +
  2791. + irq -= AR71XX_MISC_IRQ_BASE;
  2792. +
  2793. + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2794. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2795. +
  2796. + /* flush write */
  2797. + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2798. +}
  2799. +
  2800. +static struct irq_chip ar71xx_misc_irq_chip = {
  2801. + .name = "AR71XX MISC",
  2802. + .unmask = ar71xx_misc_irq_unmask,
  2803. + .mask = ar71xx_misc_irq_mask,
  2804. +};
  2805. +
  2806. +static struct irqaction ar71xx_misc_irqaction = {
  2807. + .handler = no_action,
  2808. + .name = "cascade [AR71XX MISC]",
  2809. +};
  2810. +
  2811. +static void __init ar71xx_misc_irq_init(void)
  2812. +{
  2813. + void __iomem *base = ar71xx_reset_base;
  2814. + int i;
  2815. +
  2816. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  2817. + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
  2818. +
  2819. + switch (ar71xx_soc) {
  2820. + case AR71XX_SOC_AR7240:
  2821. + case AR71XX_SOC_AR7241:
  2822. + case AR71XX_SOC_AR7242:
  2823. + ar71xx_misc_irq_chip.ack = ar724x_misc_irq_ack;
  2824. + break;
  2825. + default:
  2826. + ar71xx_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
  2827. + break;
  2828. + }
  2829. +
  2830. + for (i = AR71XX_MISC_IRQ_BASE;
  2831. + i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) {
  2832. + irq_desc[i].status = IRQ_DISABLED;
  2833. + set_irq_chip_and_handler(i, &ar71xx_misc_irq_chip,
  2834. + handle_level_irq);
  2835. + }
  2836. +
  2837. + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
  2838. +}
  2839. +
  2840. +asmlinkage void plat_irq_dispatch(void)
  2841. +{
  2842. + unsigned long pending;
  2843. +
  2844. + pending = read_c0_status() & read_c0_cause() & ST0_IM;
  2845. +
  2846. + if (pending & STATUSF_IP7)
  2847. + do_IRQ(AR71XX_CPU_IRQ_TIMER);
  2848. +
  2849. + else if (pending & STATUSF_IP2) {
  2850. + /*
  2851. + * This IRQ is meant for a PCI device. Drivers for PCI devices
  2852. + * typically allocate coherent DMA memory for the descriptor
  2853. + * ring, however the DMA controller may still have some
  2854. + * unsynchronized data in the FIFO.
  2855. + * Issue a flush here to ensure that the driver sees the update.
  2856. + */
  2857. + ar71xx_ddr_flush(ip2_flush_reg);
  2858. + do_IRQ(AR71XX_CPU_IRQ_IP2);
  2859. + }
  2860. +
  2861. + else if (pending & STATUSF_IP4)
  2862. + do_IRQ(AR71XX_CPU_IRQ_GE0);
  2863. +
  2864. + else if (pending & STATUSF_IP5)
  2865. + do_IRQ(AR71XX_CPU_IRQ_GE1);
  2866. +
  2867. + else if (pending & STATUSF_IP3)
  2868. + do_IRQ(AR71XX_CPU_IRQ_USB);
  2869. +
  2870. + else if (pending & STATUSF_IP6)
  2871. + ar71xx_misc_irq_dispatch();
  2872. +
  2873. + else
  2874. + spurious_interrupt();
  2875. +}
  2876. +
  2877. +void __init arch_init_irq(void)
  2878. +{
  2879. + switch(ar71xx_soc) {
  2880. + case AR71XX_SOC_AR7240:
  2881. + case AR71XX_SOC_AR7241:
  2882. + case AR71XX_SOC_AR7242:
  2883. + ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
  2884. + break;
  2885. + case AR71XX_SOC_AR9130:
  2886. + case AR71XX_SOC_AR9132:
  2887. + ip2_flush_reg = AR91XX_DDR_REG_FLUSH_WMAC;
  2888. + break;
  2889. + default:
  2890. + ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
  2891. + break;
  2892. + }
  2893. + mips_cpu_irq_init();
  2894. +
  2895. + ar71xx_misc_irq_init();
  2896. +
  2897. + cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC;
  2898. +
  2899. + ar71xx_gpio_irq_init();
  2900. +}
  2901. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.37/arch/mips/ar71xx/mach-ap81.c
  2902. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100
  2903. +++ linux-2.6.37/arch/mips/ar71xx/mach-ap81.c 2011-01-11 20:25:48.000000000 +0100
  2904. @@ -0,0 +1,140 @@
  2905. +/*
  2906. + * Atheros AP81 board support
  2907. + *
  2908. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  2909. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  2910. + *
  2911. + * This program is free software; you can redistribute it and/or modify it
  2912. + * under the terms of the GNU General Public License version 2 as published
  2913. + * by the Free Software Foundation.
  2914. + */
  2915. +
  2916. +#include <linux/mtd/mtd.h>
  2917. +#include <linux/mtd/partitions.h>
  2918. +
  2919. +#include <asm/mach-ar71xx/ar71xx.h>
  2920. +
  2921. +#include "machtype.h"
  2922. +#include "devices.h"
  2923. +#include "dev-m25p80.h"
  2924. +#include "dev-ar913x-wmac.h"
  2925. +#include "dev-gpio-buttons.h"
  2926. +#include "dev-leds-gpio.h"
  2927. +#include "dev-usb.h"
  2928. +
  2929. +#define AP81_GPIO_LED_STATUS 1
  2930. +#define AP81_GPIO_LED_AOSS 3
  2931. +#define AP81_GPIO_LED_WLAN 6
  2932. +#define AP81_GPIO_LED_POWER 14
  2933. +
  2934. +#define AP81_GPIO_BTN_SW4 12
  2935. +#define AP81_GPIO_BTN_SW1 21
  2936. +
  2937. +#define AP81_BUTTONS_POLL_INTERVAL 20
  2938. +
  2939. +#ifdef CONFIG_MTD_PARTITIONS
  2940. +static struct mtd_partition ap81_partitions[] = {
  2941. + {
  2942. + .name = "u-boot",
  2943. + .offset = 0,
  2944. + .size = 0x040000,
  2945. + .mask_flags = MTD_WRITEABLE,
  2946. + } , {
  2947. + .name = "u-boot-env",
  2948. + .offset = 0x040000,
  2949. + .size = 0x010000,
  2950. + } , {
  2951. + .name = "rootfs",
  2952. + .offset = 0x050000,
  2953. + .size = 0x500000,
  2954. + } , {
  2955. + .name = "uImage",
  2956. + .offset = 0x550000,
  2957. + .size = 0x100000,
  2958. + } , {
  2959. + .name = "ART",
  2960. + .offset = 0x650000,
  2961. + .size = 0x1b0000,
  2962. + .mask_flags = MTD_WRITEABLE,
  2963. + }
  2964. +};
  2965. +#endif /* CONFIG_MTD_PARTITIONS */
  2966. +
  2967. +static struct flash_platform_data ap81_flash_data = {
  2968. +#ifdef CONFIG_MTD_PARTITIONS
  2969. + .parts = ap81_partitions,
  2970. + .nr_parts = ARRAY_SIZE(ap81_partitions),
  2971. +#endif
  2972. +};
  2973. +
  2974. +static struct gpio_led ap81_leds_gpio[] __initdata = {
  2975. + {
  2976. + .name = "ap81:green:status",
  2977. + .gpio = AP81_GPIO_LED_STATUS,
  2978. + .active_low = 1,
  2979. + }, {
  2980. + .name = "ap81:amber:aoss",
  2981. + .gpio = AP81_GPIO_LED_AOSS,
  2982. + .active_low = 1,
  2983. + }, {
  2984. + .name = "ap81:green:wlan",
  2985. + .gpio = AP81_GPIO_LED_WLAN,
  2986. + .active_low = 1,
  2987. + }, {
  2988. + .name = "ap81:green:power",
  2989. + .gpio = AP81_GPIO_LED_POWER,
  2990. + .active_low = 1,
  2991. + }
  2992. +};
  2993. +
  2994. +static struct gpio_button ap81_gpio_buttons[] __initdata = {
  2995. + {
  2996. + .desc = "sw1",
  2997. + .type = EV_KEY,
  2998. + .code = BTN_0,
  2999. + .threshold = 3,
  3000. + .gpio = AP81_GPIO_BTN_SW1,
  3001. + .active_low = 1,
  3002. + } , {
  3003. + .desc = "sw4",
  3004. + .type = EV_KEY,
  3005. + .code = BTN_1,
  3006. + .threshold = 3,
  3007. + .gpio = AP81_GPIO_BTN_SW4,
  3008. + .active_low = 1,
  3009. + }
  3010. +};
  3011. +
  3012. +static void __init ap81_setup(void)
  3013. +{
  3014. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3015. +
  3016. + ar71xx_set_mac_base(eeprom);
  3017. + ar71xx_add_device_mdio(0x0);
  3018. +
  3019. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3020. + ar71xx_eth0_data.speed = SPEED_100;
  3021. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3022. + ar71xx_eth0_data.has_ar8216 = 1;
  3023. +
  3024. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3025. + ar71xx_eth1_data.phy_mask = 0x10;
  3026. +
  3027. + ar71xx_add_device_eth(0);
  3028. + ar71xx_add_device_eth(1);
  3029. +
  3030. + ar71xx_add_device_usb();
  3031. +
  3032. + ar71xx_add_device_m25p80(&ap81_flash_data);
  3033. +
  3034. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
  3035. + ap81_leds_gpio);
  3036. +
  3037. + ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL,
  3038. + ARRAY_SIZE(ap81_gpio_buttons),
  3039. + ap81_gpio_buttons);
  3040. +
  3041. + ar913x_add_device_wmac(eeprom, NULL);
  3042. +}
  3043. +
  3044. +MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup);
  3045. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.37/arch/mips/ar71xx/mach-ap83.c
  3046. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100
  3047. +++ linux-2.6.37/arch/mips/ar71xx/mach-ap83.c 2011-01-11 20:25:48.000000000 +0100
  3048. @@ -0,0 +1,266 @@
  3049. +/*
  3050. + * Atheros AP83 board support
  3051. + *
  3052. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3053. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3054. + *
  3055. + * This program is free software; you can redistribute it and/or modify it
  3056. + * under the terms of the GNU General Public License version 2 as published
  3057. + * by the Free Software Foundation.
  3058. + */
  3059. +
  3060. +#include <linux/delay.h>
  3061. +#include <linux/platform_device.h>
  3062. +#include <linux/mtd/mtd.h>
  3063. +#include <linux/mtd/partitions.h>
  3064. +#include <linux/spi/spi.h>
  3065. +#include <linux/spi/spi_gpio.h>
  3066. +#include <linux/spi/vsc7385.h>
  3067. +
  3068. +#include <asm/mach-ar71xx/ar71xx.h>
  3069. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  3070. +
  3071. +#include "machtype.h"
  3072. +#include "devices.h"
  3073. +#include "dev-ar913x-wmac.h"
  3074. +#include "dev-gpio-buttons.h"
  3075. +#include "dev-leds-gpio.h"
  3076. +#include "dev-usb.h"
  3077. +
  3078. +#define AP83_GPIO_LED_WLAN 6
  3079. +#define AP83_GPIO_LED_POWER 14
  3080. +#define AP83_GPIO_LED_JUMPSTART 15
  3081. +#define AP83_GPIO_BTN_JUMPSTART 12
  3082. +#define AP83_GPIO_BTN_RESET 21
  3083. +
  3084. +#define AP83_050_GPIO_VSC7385_CS 1
  3085. +#define AP83_050_GPIO_VSC7385_MISO 3
  3086. +#define AP83_050_GPIO_VSC7385_MOSI 16
  3087. +#define AP83_050_GPIO_VSC7385_SCK 17
  3088. +
  3089. +#define AP83_BUTTONS_POLL_INTERVAL 20
  3090. +
  3091. +#ifdef CONFIG_MTD_PARTITIONS
  3092. +static struct mtd_partition ap83_flash_partitions[] = {
  3093. + {
  3094. + .name = "u-boot",
  3095. + .offset = 0,
  3096. + .size = 0x040000,
  3097. + .mask_flags = MTD_WRITEABLE,
  3098. + } , {
  3099. + .name = "u-boot-env",
  3100. + .offset = 0x040000,
  3101. + .size = 0x020000,
  3102. + .mask_flags = MTD_WRITEABLE,
  3103. + } , {
  3104. + .name = "kernel",
  3105. + .offset = 0x060000,
  3106. + .size = 0x140000,
  3107. + } , {
  3108. + .name = "rootfs",
  3109. + .offset = 0x1a0000,
  3110. + .size = 0x650000,
  3111. + } , {
  3112. + .name = "art",
  3113. + .offset = 0x7f0000,
  3114. + .size = 0x010000,
  3115. + .mask_flags = MTD_WRITEABLE,
  3116. + } , {
  3117. + .name = "firmware",
  3118. + .offset = 0x060000,
  3119. + .size = 0x790000,
  3120. + }
  3121. +};
  3122. +#endif /* CONFIG_MTD_PARTITIONS */
  3123. +
  3124. +static struct ar91xx_flash_platform_data ap83_flash_data = {
  3125. + .width = 2,
  3126. +#ifdef CONFIG_MTD_PARTITIONS
  3127. + .parts = ap83_flash_partitions,
  3128. + .nr_parts = ARRAY_SIZE(ap83_flash_partitions),
  3129. +#endif
  3130. +};
  3131. +
  3132. +static struct resource ap83_flash_resources[] = {
  3133. + [0] = {
  3134. + .start = AR71XX_SPI_BASE,
  3135. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3136. + .flags = IORESOURCE_MEM,
  3137. + },
  3138. +};
  3139. +
  3140. +static struct platform_device ap83_flash_device = {
  3141. + .name = "ar91xx-flash",
  3142. + .id = -1,
  3143. + .resource = ap83_flash_resources,
  3144. + .num_resources = ARRAY_SIZE(ap83_flash_resources),
  3145. + .dev = {
  3146. + .platform_data = &ap83_flash_data,
  3147. + }
  3148. +};
  3149. +
  3150. +static struct gpio_led ap83_leds_gpio[] __initdata = {
  3151. + {
  3152. + .name = "ap83:green:jumpstart",
  3153. + .gpio = AP83_GPIO_LED_JUMPSTART,
  3154. + .active_low = 0,
  3155. + }, {
  3156. + .name = "ap83:green:power",
  3157. + .gpio = AP83_GPIO_LED_POWER,
  3158. + .active_low = 0,
  3159. + }, {
  3160. + .name = "ap83:green:wlan",
  3161. + .gpio = AP83_GPIO_LED_WLAN,
  3162. + .active_low = 0,
  3163. + },
  3164. +};
  3165. +
  3166. +static struct gpio_button ap83_gpio_buttons[] __initdata = {
  3167. + {
  3168. + .desc = "soft_reset",
  3169. + .type = EV_KEY,
  3170. + .code = KEY_RESTART,
  3171. + .threshold = 3,
  3172. + .gpio = AP83_GPIO_BTN_RESET,
  3173. + .active_low = 1,
  3174. + } , {
  3175. + .desc = "jumpstart",
  3176. + .type = EV_KEY,
  3177. + .code = KEY_WPS_BUTTON,
  3178. + .threshold = 3,
  3179. + .gpio = AP83_GPIO_BTN_JUMPSTART,
  3180. + .active_low = 1,
  3181. + }
  3182. +};
  3183. +
  3184. +static struct resource ap83_040_spi_resources[] = {
  3185. + [0] = {
  3186. + .start = AR71XX_SPI_BASE,
  3187. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  3188. + .flags = IORESOURCE_MEM,
  3189. + },
  3190. +};
  3191. +
  3192. +static struct platform_device ap83_040_spi_device = {
  3193. + .name = "ap83-spi",
  3194. + .id = 0,
  3195. + .resource = ap83_040_spi_resources,
  3196. + .num_resources = ARRAY_SIZE(ap83_040_spi_resources),
  3197. +};
  3198. +
  3199. +static struct spi_gpio_platform_data ap83_050_spi_data = {
  3200. + .miso = AP83_050_GPIO_VSC7385_MISO,
  3201. + .mosi = AP83_050_GPIO_VSC7385_MOSI,
  3202. + .sck = AP83_050_GPIO_VSC7385_SCK,
  3203. + .num_chipselect = 1,
  3204. +};
  3205. +
  3206. +static struct platform_device ap83_050_spi_device = {
  3207. + .name = "spi_gpio",
  3208. + .id = 0,
  3209. + .dev = {
  3210. + .platform_data = &ap83_050_spi_data,
  3211. + }
  3212. +};
  3213. +
  3214. +static void ap83_vsc7385_reset(void)
  3215. +{
  3216. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  3217. + udelay(10);
  3218. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  3219. + mdelay(50);
  3220. +}
  3221. +
  3222. +static struct vsc7385_platform_data ap83_vsc7385_data = {
  3223. + .reset = ap83_vsc7385_reset,
  3224. + .ucode_name = "vsc7385_ucode_ap83.bin",
  3225. + .mac_cfg = {
  3226. + .tx_ipg = 6,
  3227. + .bit2 = 0,
  3228. + .clk_sel = 3,
  3229. + },
  3230. +};
  3231. +
  3232. +static struct spi_board_info ap83_spi_info[] = {
  3233. + {
  3234. + .bus_num = 0,
  3235. + .chip_select = 0,
  3236. + .max_speed_hz = 25000000,
  3237. + .modalias = "spi-vsc7385",
  3238. + .platform_data = &ap83_vsc7385_data,
  3239. + .controller_data = (void *) AP83_050_GPIO_VSC7385_CS,
  3240. + }
  3241. +};
  3242. +
  3243. +static void __init ap83_generic_setup(void)
  3244. +{
  3245. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3246. +
  3247. + ar71xx_set_mac_base(eeprom);
  3248. +
  3249. + ar71xx_add_device_mdio(0xfffffffe);
  3250. +
  3251. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3252. + ar71xx_eth0_data.phy_mask = 0x1;
  3253. +
  3254. + ar71xx_add_device_eth(0);
  3255. +
  3256. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3257. + ar71xx_eth1_data.speed = SPEED_1000;
  3258. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  3259. +
  3260. + ar71xx_eth1_pll_data.pll_1000 = 0x1f000000;
  3261. +
  3262. + ar71xx_add_device_eth(1);
  3263. +
  3264. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
  3265. + ap83_leds_gpio);
  3266. +
  3267. + ar71xx_add_device_gpio_buttons(-1, AP83_BUTTONS_POLL_INTERVAL,
  3268. + ARRAY_SIZE(ap83_gpio_buttons),
  3269. + ap83_gpio_buttons);
  3270. +
  3271. + ar71xx_add_device_usb();
  3272. +
  3273. + ar913x_add_device_wmac(eeprom, NULL);
  3274. +
  3275. + platform_device_register(&ap83_flash_device);
  3276. +
  3277. + spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info));
  3278. +}
  3279. +
  3280. +static void __init ap83_040_setup(void)
  3281. +{
  3282. + ap83_flash_data.is_shared=1;
  3283. + ap83_generic_setup();
  3284. + platform_device_register(&ap83_040_spi_device);
  3285. +}
  3286. +
  3287. +static void __init ap83_050_setup(void)
  3288. +{
  3289. + ap83_generic_setup();
  3290. + platform_device_register(&ap83_050_spi_device);
  3291. +}
  3292. +
  3293. +static void __init ap83_setup(void)
  3294. +{
  3295. + u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244);
  3296. + unsigned int board_version;
  3297. +
  3298. + board_version = (unsigned int)(board_id[0] - '0');
  3299. + board_version += ((unsigned int)(board_id[1] - '0')) * 10;
  3300. +
  3301. + switch (board_version) {
  3302. + case 40:
  3303. + ap83_040_setup();
  3304. + break;
  3305. + case 50:
  3306. + ap83_050_setup();
  3307. + break;
  3308. + default:
  3309. + printk(KERN_WARNING "AP83-%03u board is not yet supported\n",
  3310. + board_version);
  3311. + }
  3312. +}
  3313. +
  3314. +MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup);
  3315. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.37/arch/mips/ar71xx/mach-aw-nr580.c
  3316. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100
  3317. +++ linux-2.6.37/arch/mips/ar71xx/mach-aw-nr580.c 2011-01-11 20:25:48.000000000 +0100
  3318. @@ -0,0 +1,101 @@
  3319. +/*
  3320. + * AzureWave AW-NR580 board support
  3321. + *
  3322. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3323. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3324. + *
  3325. + * This program is free software; you can redistribute it and/or modify it
  3326. + * under the terms of the GNU General Public License version 2 as published
  3327. + * by the Free Software Foundation.
  3328. + */
  3329. +
  3330. +#include <linux/mtd/mtd.h>
  3331. +#include <linux/mtd/partitions.h>
  3332. +
  3333. +#include <asm/mips_machine.h>
  3334. +#include <asm/mach-ar71xx/ar71xx.h>
  3335. +
  3336. +#include "machtype.h"
  3337. +#include "devices.h"
  3338. +#include "dev-m25p80.h"
  3339. +#include "dev-gpio-buttons.h"
  3340. +#include "dev-pb42-pci.h"
  3341. +#include "dev-leds-gpio.h"
  3342. +
  3343. +#define AW_NR580_GPIO_LED_READY_RED 0
  3344. +#define AW_NR580_GPIO_LED_WLAN 1
  3345. +#define AW_NR580_GPIO_LED_READY_GREEN 2
  3346. +#define AW_NR580_GPIO_LED_WPS_GREEN 4
  3347. +#define AW_NR580_GPIO_LED_WPS_AMBER 5
  3348. +
  3349. +#define AW_NR580_GPIO_BTN_WPS 3
  3350. +#define AW_NR580_GPIO_BTN_RESET 11
  3351. +
  3352. +#define AW_NR580_BUTTONS_POLL_INTERVAL 20
  3353. +
  3354. +static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
  3355. + {
  3356. + .name = "aw-nr580:red:ready",
  3357. + .gpio = AW_NR580_GPIO_LED_READY_RED,
  3358. + .active_low = 0,
  3359. + }, {
  3360. + .name = "aw-nr580:green:ready",
  3361. + .gpio = AW_NR580_GPIO_LED_READY_GREEN,
  3362. + .active_low = 0,
  3363. + }, {
  3364. + .name = "aw-nr580:green:wps",
  3365. + .gpio = AW_NR580_GPIO_LED_WPS_GREEN,
  3366. + .active_low = 0,
  3367. + }, {
  3368. + .name = "aw-nr580:amber:wps",
  3369. + .gpio = AW_NR580_GPIO_LED_WPS_AMBER,
  3370. + .active_low = 0,
  3371. + }, {
  3372. + .name = "aw-nr580:green:wlan",
  3373. + .gpio = AW_NR580_GPIO_LED_WLAN,
  3374. + .active_low = 0,
  3375. + }
  3376. +};
  3377. +
  3378. +static struct gpio_button aw_nr580_gpio_buttons[] __initdata = {
  3379. + {
  3380. + .desc = "reset",
  3381. + .type = EV_KEY,
  3382. + .code = KEY_RESTART,
  3383. + .threshold = 3,
  3384. + .gpio = AW_NR580_GPIO_BTN_RESET,
  3385. + .active_low = 1,
  3386. + }, {
  3387. + .desc = "wps",
  3388. + .type = EV_KEY,
  3389. + .code = KEY_WPS_BUTTON,
  3390. + .threshold = 3,
  3391. + .gpio = AW_NR580_GPIO_BTN_WPS,
  3392. + .active_low = 1,
  3393. + }
  3394. +};
  3395. +
  3396. +static void __init aw_nr580_setup(void)
  3397. +{
  3398. + ar71xx_add_device_mdio(0x0);
  3399. +
  3400. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  3401. + ar71xx_eth0_data.speed = SPEED_100;
  3402. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3403. +
  3404. + ar71xx_add_device_eth(0);
  3405. +
  3406. + pb42_pci_init();
  3407. +
  3408. + ar71xx_add_device_m25p80(NULL);
  3409. +
  3410. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
  3411. + aw_nr580_leds_gpio);
  3412. +
  3413. + ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL,
  3414. + ARRAY_SIZE(aw_nr580_gpio_buttons),
  3415. + aw_nr580_gpio_buttons);
  3416. +}
  3417. +
  3418. +MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580",
  3419. + aw_nr580_setup);
  3420. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.37/arch/mips/ar71xx/mach-dir-600-a1.c
  3421. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100
  3422. +++ linux-2.6.37/arch/mips/ar71xx/mach-dir-600-a1.c 2011-01-11 20:25:48.000000000 +0100
  3423. @@ -0,0 +1,138 @@
  3424. +/*
  3425. + * D-Link DIR-600 rev. A1 board support
  3426. + *
  3427. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  3428. + *
  3429. + * This program is free software; you can redistribute it and/or modify it
  3430. + * under the terms of the GNU General Public License version 2 as published
  3431. + * by the Free Software Foundation.
  3432. + */
  3433. +
  3434. +#include <linux/mtd/mtd.h>
  3435. +#include <linux/mtd/partitions.h>
  3436. +
  3437. +#include <asm/mach-ar71xx/ar71xx.h>
  3438. +
  3439. +#include "machtype.h"
  3440. +#include "devices.h"
  3441. +#include "dev-m25p80.h"
  3442. +#include "dev-ap91-eth.h"
  3443. +#include "dev-ap91-pci.h"
  3444. +#include "dev-gpio-buttons.h"
  3445. +#include "dev-leds-gpio.h"
  3446. +#include "nvram.h"
  3447. +
  3448. +#define DIR_600_A1_GPIO_LED_WPS 0
  3449. +#define DIR_600_A1_GPIO_LED_POWER_AMBER 1
  3450. +#define DIR_600_A1_GPIO_LED_POWER_GREEN 6
  3451. +
  3452. +#define DIR_600_A1_GPIO_BTN_RESET 8
  3453. +#define DIR_600_A1_GPIO_BTN_WPS 12
  3454. +
  3455. +#define DIR_600_A1_BUTTONS_POLL_INTERVAL 20
  3456. +
  3457. +#define DIR_600_A1_NVRAM_ADDR 0x1f030000
  3458. +#define DIR_600_A1_NVRAM_SIZE 0x10000
  3459. +
  3460. +#ifdef CONFIG_MTD_PARTITIONS
  3461. +static struct mtd_partition dir_600_a1_partitions[] = {
  3462. + {
  3463. + .name = "u-boot",
  3464. + .offset = 0,
  3465. + .size = 0x030000,
  3466. + .mask_flags = MTD_WRITEABLE,
  3467. + }, {
  3468. + .name = "nvram",
  3469. + .offset = 0x030000,
  3470. + .size = 0x010000,
  3471. + }, {
  3472. + .name = "kernel",
  3473. + .offset = 0x040000,
  3474. + .size = 0x0e0000,
  3475. + }, {
  3476. + .name = "rootfs",
  3477. + .offset = 0x120000,
  3478. + .size = 0x2c0000,
  3479. + }, {
  3480. + .name = "mac",
  3481. + .offset = 0x3e0000,
  3482. + .size = 0x010000,
  3483. + .mask_flags = MTD_WRITEABLE,
  3484. + }, {
  3485. + .name = "art",
  3486. + .offset = 0x3f0000,
  3487. + .size = 0x010000,
  3488. + .mask_flags = MTD_WRITEABLE,
  3489. + }, {
  3490. + .name = "firmware",
  3491. + .offset = 0x040000,
  3492. + .size = 0x3a0000,
  3493. + }
  3494. +};
  3495. +#endif /* CONFIG_MTD_PARTITIONS */
  3496. +
  3497. +static struct flash_platform_data dir_600_a1_flash_data = {
  3498. +#ifdef CONFIG_MTD_PARTITIONS
  3499. + .parts = dir_600_a1_partitions,
  3500. + .nr_parts = ARRAY_SIZE(dir_600_a1_partitions),
  3501. +#endif
  3502. +};
  3503. +
  3504. +static struct gpio_led dir_600_a1_leds_gpio[] __initdata = {
  3505. + {
  3506. + .name = "dir-600-a1:green:power",
  3507. + .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN,
  3508. + }, {
  3509. + .name = "dir-600-a1:amber:power",
  3510. + .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER,
  3511. + }, {
  3512. + .name = "dir-600-a1:blue:wps",
  3513. + .gpio = DIR_600_A1_GPIO_LED_WPS,
  3514. + .active_low = 1,
  3515. + }
  3516. +};
  3517. +
  3518. +static struct gpio_button dir_600_a1_gpio_buttons[] __initdata = {
  3519. + {
  3520. + .desc = "reset",
  3521. + .type = EV_KEY,
  3522. + .code = KEY_RESTART,
  3523. + .threshold = 3,
  3524. + .gpio = DIR_600_A1_GPIO_BTN_RESET,
  3525. + .active_low = 1,
  3526. + }, {
  3527. + .desc = "wps",
  3528. + .type = EV_KEY,
  3529. + .code = KEY_WPS_BUTTON,
  3530. + .threshold = 3,
  3531. + .gpio = DIR_600_A1_GPIO_BTN_WPS,
  3532. + .active_low = 1,
  3533. + }
  3534. +};
  3535. +
  3536. +static void __init dir_600_a1_setup(void)
  3537. +{
  3538. + const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR);
  3539. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  3540. + u8 mac_buff[6];
  3541. + u8 *mac = NULL;
  3542. +
  3543. + if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE,
  3544. + "lan_mac=", mac_buff) == 0)
  3545. + mac = mac_buff;
  3546. +
  3547. + ar71xx_add_device_m25p80(&dir_600_a1_flash_data);
  3548. +
  3549. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio),
  3550. + dir_600_a1_leds_gpio);
  3551. +
  3552. + ar71xx_add_device_gpio_buttons(-1, DIR_600_A1_BUTTONS_POLL_INTERVAL,
  3553. + ARRAY_SIZE(dir_600_a1_gpio_buttons),
  3554. + dir_600_a1_gpio_buttons);
  3555. +
  3556. + ap91_eth_init(mac, NULL);
  3557. + ap91_pci_init(ee, mac);
  3558. +}
  3559. +
  3560. +MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1",
  3561. + dir_600_a1_setup);
  3562. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.37/arch/mips/ar71xx/mach-dir-615-c1.c
  3563. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100
  3564. +++ linux-2.6.37/arch/mips/ar71xx/mach-dir-615-c1.c 2011-01-11 20:25:48.000000000 +0100
  3565. @@ -0,0 +1,173 @@
  3566. +/*
  3567. + * D-Link DIR-615 rev C1 board support
  3568. + *
  3569. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  3570. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  3571. + *
  3572. + * This program is free software; you can redistribute it and/or modify it
  3573. + * under the terms of the GNU General Public License version 2 as published
  3574. + * by the Free Software Foundation.
  3575. + */
  3576. +
  3577. +#include <linux/mtd/mtd.h>
  3578. +#include <linux/mtd/partitions.h>
  3579. +
  3580. +#include <asm/mach-ar71xx/ar71xx.h>
  3581. +
  3582. +#include "machtype.h"
  3583. +#include "devices.h"
  3584. +#include "dev-m25p80.h"
  3585. +#include "dev-ar913x-wmac.h"
  3586. +#include "dev-gpio-buttons.h"
  3587. +#include "dev-leds-gpio.h"
  3588. +#include "nvram.h"
  3589. +
  3590. +#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */
  3591. +#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */
  3592. +#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */
  3593. +#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */
  3594. +#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */
  3595. +#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */
  3596. +#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */
  3597. +
  3598. +/* buttons may need refinement */
  3599. +
  3600. +#define DIR_615C1_GPIO_BTN_WPS 12
  3601. +#define DIR_615C1_GPIO_BTN_RESET 21
  3602. +
  3603. +#define DIR_615C1_BUTTONS_POLL_INTERVAL 20
  3604. +
  3605. +#define DIR_615C1_CONFIG_ADDR 0x1f020000
  3606. +#define DIR_615C1_CONFIG_SIZE 0x10000
  3607. +
  3608. +#ifdef CONFIG_MTD_PARTITIONS
  3609. +static struct mtd_partition dir_615c1_partitions[] = {
  3610. + {
  3611. + .name = "u-boot",
  3612. + .offset = 0,
  3613. + .size = 0x020000,
  3614. + .mask_flags = MTD_WRITEABLE,
  3615. + } , {
  3616. + .name = "config",
  3617. + .offset = 0x020000,
  3618. + .size = 0x010000,
  3619. + } , {
  3620. + .name = "kernel",
  3621. + .offset = 0x030000,
  3622. + .size = 0x0d0000,
  3623. + } , {
  3624. + .name = "rootfs",
  3625. + .offset = 0x100000,
  3626. + .size = 0x2f0000,
  3627. + } , {
  3628. + .name = "art",
  3629. + .offset = 0x3f0000,
  3630. + .size = 0x010000,
  3631. + .mask_flags = MTD_WRITEABLE,
  3632. + } , {
  3633. + .name = "firmware",
  3634. + .offset = 0x030000,
  3635. + .size = 0x3c0000,
  3636. + }
  3637. +};
  3638. +#endif /* CONFIG_MTD_PARTITIONS */
  3639. +
  3640. +static struct flash_platform_data dir_615c1_flash_data = {
  3641. +#ifdef CONFIG_MTD_PARTITIONS
  3642. + .parts = dir_615c1_partitions,
  3643. + .nr_parts = ARRAY_SIZE(dir_615c1_partitions),
  3644. +#endif
  3645. +};
  3646. +
  3647. +static struct gpio_led dir_615c1_leds_gpio[] __initdata = {
  3648. + {
  3649. + .name = "dir-615c1:orange:status",
  3650. + .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS,
  3651. + .active_low = 1,
  3652. + }, {
  3653. + .name = "dir-615c1:blue:wps",
  3654. + .gpio = DIR_615C1_GPIO_LED_BLUE_WPS,
  3655. + .active_low = 1,
  3656. + }, {
  3657. + .name = "dir-615c1:green:wan",
  3658. + .gpio = DIR_615C1_GPIO_LED_GREEN_WAN,
  3659. + .active_low = 1,
  3660. + }, {
  3661. + .name = "dir-615c1:green:wancpu",
  3662. + .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU,
  3663. + .active_low = 1,
  3664. + }, {
  3665. + .name = "dir-615c1:green:wlan",
  3666. + .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN,
  3667. + .active_low = 1,
  3668. + }, {
  3669. + .name = "dir-615c1:green:status",
  3670. + .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS,
  3671. + .active_low = 1,
  3672. + }, {
  3673. + .name = "dir-615c1:orange:wan",
  3674. + .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN,
  3675. + .active_low = 1,
  3676. + }
  3677. +
  3678. +};
  3679. +
  3680. +static struct gpio_button dir_615c1_gpio_buttons[] __initdata = {
  3681. + {
  3682. + .desc = "reset",
  3683. + .type = EV_KEY,
  3684. + .code = KEY_RESTART,
  3685. + .threshold = 3,
  3686. + .gpio = DIR_615C1_GPIO_BTN_RESET,
  3687. + }, {
  3688. + .desc = "wps",
  3689. + .type = EV_KEY,
  3690. + .code = KEY_WPS_BUTTON,
  3691. + .threshold = 3,
  3692. + .gpio = DIR_615C1_GPIO_BTN_WPS,
  3693. + }
  3694. +};
  3695. +
  3696. +#define DIR_615C1_LAN_PHYMASK BIT(0)
  3697. +#define DIR_615C1_WAN_PHYMASK BIT(4)
  3698. +#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \
  3699. + DIR_615C1_WAN_PHYMASK))
  3700. +
  3701. +static void __init dir_615c1_setup(void)
  3702. +{
  3703. + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR);
  3704. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  3705. + u8 mac[6];
  3706. + u8 *wlan_mac = NULL;
  3707. +
  3708. + if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE,
  3709. + "lan_mac=", mac) == 0) {
  3710. + ar71xx_set_mac_base(mac);
  3711. + wlan_mac = mac;
  3712. + }
  3713. +
  3714. + ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK);
  3715. +
  3716. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3717. + ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK;
  3718. +
  3719. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  3720. + ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK;
  3721. +
  3722. + ar71xx_add_device_eth(0);
  3723. + ar71xx_add_device_eth(1);
  3724. +
  3725. + ar71xx_add_device_m25p80(&dir_615c1_flash_data);
  3726. +
  3727. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio),
  3728. + dir_615c1_leds_gpio);
  3729. +
  3730. + ar71xx_add_device_gpio_buttons(-1, DIR_615C1_BUTTONS_POLL_INTERVAL,
  3731. + ARRAY_SIZE(dir_615c1_gpio_buttons),
  3732. + dir_615c1_gpio_buttons);
  3733. +
  3734. + ar913x_add_device_wmac(eeprom, wlan_mac);
  3735. +}
  3736. +
  3737. +MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1",
  3738. + dir_615c1_setup);
  3739. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.37/arch/mips/ar71xx/mach-dir-825-b1.c
  3740. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100
  3741. +++ linux-2.6.37/arch/mips/ar71xx/mach-dir-825-b1.c 2011-01-11 20:25:48.000000000 +0100
  3742. @@ -0,0 +1,192 @@
  3743. +/*
  3744. + * D-Link DIR-825 rev. B1 board support
  3745. + *
  3746. + * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o.
  3747. + *
  3748. + * based on mach-wndr3700.c
  3749. + *
  3750. + * This program is free software; you can redistribute it and/or modify it
  3751. + * under the terms of the GNU General Public License version 2 as published
  3752. + * by the Free Software Foundation.
  3753. + */
  3754. +
  3755. +#include <linux/platform_device.h>
  3756. +#include <linux/mtd/mtd.h>
  3757. +#include <linux/mtd/partitions.h>
  3758. +#include <linux/delay.h>
  3759. +#include <linux/rtl8366s.h>
  3760. +
  3761. +#include <asm/mach-ar71xx/ar71xx.h>
  3762. +
  3763. +#include "machtype.h"
  3764. +#include "devices.h"
  3765. +#include "dev-m25p80.h"
  3766. +#include "dev-ap94-pci.h"
  3767. +#include "dev-gpio-buttons.h"
  3768. +#include "dev-leds-gpio.h"
  3769. +#include "dev-usb.h"
  3770. +
  3771. +#define DIR825B1_GPIO_LED_BLUE_USB 0
  3772. +#define DIR825B1_GPIO_LED_ORANGE_POWER 1
  3773. +#define DIR825B1_GPIO_LED_BLUE_POWER 2
  3774. +#define DIR825B1_GPIO_LED_BLUE_POWERSAVE 4
  3775. +#define DIR825B1_GPIO_LED_ORANGE_PLANET 6
  3776. +#define DIR825B1_GPIO_LED_BLUE_PLANET 11
  3777. +
  3778. +#define DIR825B1_GPIO_BTN_RESET 3
  3779. +#define DIR825B1_GPIO_BTN_POWERSAVE 8
  3780. +
  3781. +#define DIR825B1_GPIO_RTL8366_SDA 5
  3782. +#define DIR825B1_GPIO_RTL8366_SCK 7
  3783. +
  3784. +#define DIR825B1_BUTTONS_POLL_INTERVAL 20
  3785. +
  3786. +#define DIR825B1_CAL_LOCATION_0 0x1f661000
  3787. +#define DIR825B1_CAL_LOCATION_1 0x1f665000
  3788. +
  3789. +#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8
  3790. +#define DIR825B1_MAC_LOCATION_1 0x2ffa8370
  3791. +
  3792. +#ifdef CONFIG_MTD_PARTITIONS
  3793. +static struct mtd_partition dir825b1_partitions[] = {
  3794. + {
  3795. + .name = "uboot",
  3796. + .offset = 0,
  3797. + .size = 0x040000,
  3798. + .mask_flags = MTD_WRITEABLE,
  3799. + } , {
  3800. + .name = "config",
  3801. + .offset = 0x040000,
  3802. + .size = 0x010000,
  3803. + .mask_flags = MTD_WRITEABLE,
  3804. + } , {
  3805. + .name = "firmware",
  3806. + .offset = 0x050000,
  3807. + .size = 0x610000,
  3808. + } , {
  3809. + .name = "caldata",
  3810. + .offset = 0x660000,
  3811. + .size = 0x010000,
  3812. + .mask_flags = MTD_WRITEABLE,
  3813. + } , {
  3814. + .name = "unknown",
  3815. + .offset = 0x670000,
  3816. + .size = 0x190000,
  3817. + .mask_flags = MTD_WRITEABLE,
  3818. + }
  3819. +};
  3820. +#endif /* CONFIG_MTD_PARTITIONS */
  3821. +
  3822. +static struct flash_platform_data dir825b1_flash_data = {
  3823. +#ifdef CONFIG_MTD_PARTITIONS
  3824. + .parts = dir825b1_partitions,
  3825. + .nr_parts = ARRAY_SIZE(dir825b1_partitions),
  3826. +#endif
  3827. +};
  3828. +
  3829. +static struct gpio_led dir825b1_leds_gpio[] __initdata = {
  3830. + {
  3831. + .name = "dir825b1:blue:usb",
  3832. + .gpio = DIR825B1_GPIO_LED_BLUE_USB,
  3833. + .active_low = 1,
  3834. + }, {
  3835. + .name = "dir825b1:orange:power",
  3836. + .gpio = DIR825B1_GPIO_LED_ORANGE_POWER,
  3837. + .active_low = 1,
  3838. + }, {
  3839. + .name = "dir825b1:blue:power",
  3840. + .gpio = DIR825B1_GPIO_LED_BLUE_POWER,
  3841. + .active_low = 1,
  3842. + }, {
  3843. + .name = "dir825b1:blue:powersave",
  3844. + .gpio = DIR825B1_GPIO_LED_BLUE_POWERSAVE,
  3845. + .active_low = 1,
  3846. + }, {
  3847. + .name = "dir825b1:orange:planet",
  3848. + .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET,
  3849. + .active_low = 1,
  3850. + }, {
  3851. + .name = "dir825b1:blue:planet",
  3852. + .gpio = DIR825B1_GPIO_LED_BLUE_PLANET,
  3853. + .active_low = 1,
  3854. + }
  3855. +};
  3856. +
  3857. +static struct gpio_button dir825b1_gpio_buttons[] __initdata = {
  3858. + {
  3859. + .desc = "reset",
  3860. + .type = EV_KEY,
  3861. + .code = KEY_RESTART,
  3862. + .threshold = 3,
  3863. + .gpio = DIR825B1_GPIO_BTN_RESET,
  3864. + .active_low = 1,
  3865. + } , {
  3866. + .desc = "powersave",
  3867. + .type = EV_KEY,
  3868. + .code = BTN_1,
  3869. + .threshold = 3,
  3870. + .gpio = DIR825B1_GPIO_BTN_POWERSAVE,
  3871. + .active_low = 1,
  3872. + }
  3873. +};
  3874. +
  3875. +static struct rtl8366s_platform_data dir825b1_rtl8366s_data = {
  3876. + .gpio_sda = DIR825B1_GPIO_RTL8366_SDA,
  3877. + .gpio_sck = DIR825B1_GPIO_RTL8366_SCK,
  3878. +};
  3879. +
  3880. +static struct platform_device dir825b1_rtl8366s_device = {
  3881. + .name = RTL8366S_DRIVER_NAME,
  3882. + .id = -1,
  3883. + .dev = {
  3884. + .platform_data = &dir825b1_rtl8366s_data,
  3885. + }
  3886. +};
  3887. +
  3888. +static void __init dir825b1_setup(void)
  3889. +{
  3890. + u8 mac[6], i;
  3891. +
  3892. + memcpy(mac, (u8*)KSEG1ADDR(DIR825B1_MAC_LOCATION_1), 6);
  3893. + for(i = 5; i >= 3; i--)
  3894. + if(++mac[i] != 0x00) break;
  3895. +
  3896. + ar71xx_set_mac_base(mac);
  3897. +
  3898. + ar71xx_add_device_mdio(0x0);
  3899. +
  3900. + ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3901. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3902. + ar71xx_eth0_data.speed = SPEED_1000;
  3903. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  3904. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  3905. +
  3906. + ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev;
  3907. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  3908. + ar71xx_eth1_data.phy_mask = 0x10;
  3909. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  3910. +
  3911. + ar71xx_add_device_eth(0);
  3912. + ar71xx_add_device_eth(1);
  3913. +
  3914. + ar71xx_add_device_m25p80(&dir825b1_flash_data);
  3915. +
  3916. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio),
  3917. + dir825b1_leds_gpio);
  3918. +
  3919. + ar71xx_add_device_gpio_buttons(-1, DIR825B1_BUTTONS_POLL_INTERVAL,
  3920. + ARRAY_SIZE(dir825b1_gpio_buttons),
  3921. + dir825b1_gpio_buttons);
  3922. +
  3923. + ar71xx_add_device_usb();
  3924. +
  3925. + platform_device_register(&dir825b1_rtl8366s_device);
  3926. +
  3927. + ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0),
  3928. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0),
  3929. + (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1),
  3930. + (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1));
  3931. +}
  3932. +
  3933. +MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1",
  3934. + dir825b1_setup);
  3935. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.37/arch/mips/ar71xx/mach-mzk-w04nu.c
  3936. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100
  3937. +++ linux-2.6.37/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-01-11 20:25:48.000000000 +0100
  3938. @@ -0,0 +1,165 @@
  3939. +/*
  3940. + * Planex MZK-W04NU board support
  3941. + *
  3942. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  3943. + *
  3944. + * This program is free software; you can redistribute it and/or modify it
  3945. + * under the terms of the GNU General Public License version 2 as published
  3946. + * by the Free Software Foundation.
  3947. + */
  3948. +
  3949. +#include <linux/mtd/mtd.h>
  3950. +#include <linux/mtd/partitions.h>
  3951. +
  3952. +#include <asm/mach-ar71xx/ar71xx.h>
  3953. +
  3954. +#include "machtype.h"
  3955. +#include "devices.h"
  3956. +#include "dev-ar913x-wmac.h"
  3957. +#include "dev-gpio-buttons.h"
  3958. +#include "dev-leds-gpio.h"
  3959. +#include "dev-m25p80.h"
  3960. +#include "dev-usb.h"
  3961. +
  3962. +#define MZK_W04NU_GPIO_LED_USB 0
  3963. +#define MZK_W04NU_GPIO_LED_STATUS 1
  3964. +#define MZK_W04NU_GPIO_LED_WPS 3
  3965. +#define MZK_W04NU_GPIO_LED_WLAN 6
  3966. +#define MZK_W04NU_GPIO_LED_AP 15
  3967. +#define MZK_W04NU_GPIO_LED_ROUTER 16
  3968. +
  3969. +#define MZK_W04NU_GPIO_BTN_APROUTER 5
  3970. +#define MZK_W04NU_GPIO_BTN_WPS 12
  3971. +#define MZK_W04NU_GPIO_BTN_RESET 21
  3972. +
  3973. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  3974. +
  3975. +#ifdef CONFIG_MTD_PARTITIONS
  3976. +static struct mtd_partition mzk_w04nu_partitions[] = {
  3977. + {
  3978. + .name = "u-boot",
  3979. + .offset = 0,
  3980. + .size = 0x040000,
  3981. + .mask_flags = MTD_WRITEABLE,
  3982. + } , {
  3983. + .name = "u-boot-env",
  3984. + .offset = 0x040000,
  3985. + .size = 0x010000,
  3986. + } , {
  3987. + .name = "kernel",
  3988. + .offset = 0x050000,
  3989. + .size = 0x160000,
  3990. + } , {
  3991. + .name = "rootfs",
  3992. + .offset = 0x1b0000,
  3993. + .size = 0x630000,
  3994. + } , {
  3995. + .name = "art",
  3996. + .offset = 0x7e0000,
  3997. + .size = 0x020000,
  3998. + .mask_flags = MTD_WRITEABLE,
  3999. + } , {
  4000. + .name = "firmware",
  4001. + .offset = 0x050000,
  4002. + .size = 0x790000,
  4003. + }
  4004. +};
  4005. +#endif /* CONFIG_MTD_PARTITIONS */
  4006. +
  4007. +static struct flash_platform_data mzk_w04nu_flash_data = {
  4008. +#ifdef CONFIG_MTD_PARTITIONS
  4009. + .parts = mzk_w04nu_partitions,
  4010. + .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions),
  4011. +#endif
  4012. +};
  4013. +
  4014. +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
  4015. + {
  4016. + .name = "mzk-w04nu:green:status",
  4017. + .gpio = MZK_W04NU_GPIO_LED_STATUS,
  4018. + .active_low = 1,
  4019. + }, {
  4020. + .name = "mzk-w04nu:blue:wps",
  4021. + .gpio = MZK_W04NU_GPIO_LED_WPS,
  4022. + .active_low = 1,
  4023. + }, {
  4024. + .name = "mzk-w04nu:green:wlan",
  4025. + .gpio = MZK_W04NU_GPIO_LED_WLAN,
  4026. + .active_low = 1,
  4027. + }, {
  4028. + .name = "mzk-w04nu:green:usb",
  4029. + .gpio = MZK_W04NU_GPIO_LED_USB,
  4030. + .active_low = 1,
  4031. + }, {
  4032. + .name = "mzk-w04nu:green:ap",
  4033. + .gpio = MZK_W04NU_GPIO_LED_AP,
  4034. + .active_low = 1,
  4035. + }, {
  4036. + .name = "mzk-w04nu:green:router",
  4037. + .gpio = MZK_W04NU_GPIO_LED_ROUTER,
  4038. + .active_low = 1,
  4039. + }
  4040. +};
  4041. +
  4042. +static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = {
  4043. + {
  4044. + .desc = "reset",
  4045. + .type = EV_KEY,
  4046. + .code = KEY_RESTART,
  4047. + .threshold = 3,
  4048. + .gpio = MZK_W04NU_GPIO_BTN_RESET,
  4049. + .active_low = 1,
  4050. + }, {
  4051. + .desc = "wps",
  4052. + .type = EV_KEY,
  4053. + .code = KEY_WPS_BUTTON,
  4054. + .threshold = 3,
  4055. + .gpio = MZK_W04NU_GPIO_BTN_WPS,
  4056. + .active_low = 1,
  4057. + }, {
  4058. + .desc = "aprouter",
  4059. + .type = EV_KEY,
  4060. + .code = BTN_2,
  4061. + .threshold = 3,
  4062. + .gpio = MZK_W04NU_GPIO_BTN_APROUTER,
  4063. + .active_low = 0,
  4064. + }
  4065. +};
  4066. +
  4067. +#define MZK_W04NU_WAN_PHYMASK BIT(4)
  4068. +#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK)
  4069. +
  4070. +static void __init mzk_w04nu_setup(void)
  4071. +{
  4072. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4073. +
  4074. + ar71xx_set_mac_base(eeprom);
  4075. +
  4076. + ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK);
  4077. +
  4078. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4079. + ar71xx_eth0_data.speed = SPEED_100;
  4080. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4081. + ar71xx_eth0_data.has_ar8216 = 1;
  4082. +
  4083. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4084. + ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK;
  4085. +
  4086. + ar71xx_add_device_eth(0);
  4087. + ar71xx_add_device_eth(1);
  4088. +
  4089. + ar71xx_add_device_m25p80(&mzk_w04nu_flash_data);
  4090. +
  4091. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
  4092. + mzk_w04nu_leds_gpio);
  4093. +
  4094. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4095. + ARRAY_SIZE(mzk_w04nu_gpio_buttons),
  4096. + mzk_w04nu_gpio_buttons);
  4097. + ar71xx_add_device_usb();
  4098. +
  4099. + ar913x_add_device_wmac(eeprom, NULL);
  4100. +}
  4101. +
  4102. +MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU",
  4103. + mzk_w04nu_setup);
  4104. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.37/arch/mips/ar71xx/mach-mzk-w300nh.c
  4105. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100
  4106. +++ linux-2.6.37/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-01-11 20:25:48.000000000 +0100
  4107. @@ -0,0 +1,158 @@
  4108. +/*
  4109. + * Planex MZK-W300NH board support
  4110. + *
  4111. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4112. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4113. + *
  4114. + * This program is free software; you can redistribute it and/or modify it
  4115. + * under the terms of the GNU General Public License version 2 as published
  4116. + * by the Free Software Foundation.
  4117. + */
  4118. +
  4119. +#include <linux/mtd/mtd.h>
  4120. +#include <linux/mtd/partitions.h>
  4121. +
  4122. +#include <asm/mach-ar71xx/ar71xx.h>
  4123. +
  4124. +#include "machtype.h"
  4125. +#include "devices.h"
  4126. +#include "dev-m25p80.h"
  4127. +#include "dev-ar913x-wmac.h"
  4128. +#include "dev-gpio-buttons.h"
  4129. +#include "dev-leds-gpio.h"
  4130. +
  4131. +#define MZK_W300NH_GPIO_LED_STATUS 1
  4132. +#define MZK_W300NH_GPIO_LED_WPS 3
  4133. +#define MZK_W300NH_GPIO_LED_WLAN 6
  4134. +#define MZK_W300NH_GPIO_LED_AP 15
  4135. +#define MZK_W300NH_GPIO_LED_ROUTER 16
  4136. +
  4137. +#define MZK_W300NH_GPIO_BTN_APROUTER 5
  4138. +#define MZK_W300NH_GPIO_BTN_WPS 12
  4139. +#define MZK_W300NH_GPIO_BTN_RESET 21
  4140. +
  4141. +#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20
  4142. +
  4143. +#ifdef CONFIG_MTD_PARTITIONS
  4144. +static struct mtd_partition mzk_w300nh_partitions[] = {
  4145. + {
  4146. + .name = "u-boot",
  4147. + .offset = 0,
  4148. + .size = 0x040000,
  4149. + .mask_flags = MTD_WRITEABLE,
  4150. + } , {
  4151. + .name = "u-boot-env",
  4152. + .offset = 0x040000,
  4153. + .size = 0x010000,
  4154. + } , {
  4155. + .name = "kernel",
  4156. + .offset = 0x050000,
  4157. + .size = 0x160000,
  4158. + } , {
  4159. + .name = "rootfs",
  4160. + .offset = 0x1b0000,
  4161. + .size = 0x630000,
  4162. + } , {
  4163. + .name = "art",
  4164. + .offset = 0x7e0000,
  4165. + .size = 0x020000,
  4166. + .mask_flags = MTD_WRITEABLE,
  4167. + } , {
  4168. + .name = "firmware",
  4169. + .offset = 0x050000,
  4170. + .size = 0x790000,
  4171. + }
  4172. +};
  4173. +#endif /* CONFIG_MTD_PARTITIONS */
  4174. +
  4175. +static struct flash_platform_data mzk_w300nh_flash_data = {
  4176. +#ifdef CONFIG_MTD_PARTITIONS
  4177. + .parts = mzk_w300nh_partitions,
  4178. + .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions),
  4179. +#endif
  4180. +};
  4181. +
  4182. +static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = {
  4183. + {
  4184. + .name = "mzk-w300nh:green:status",
  4185. + .gpio = MZK_W300NH_GPIO_LED_STATUS,
  4186. + .active_low = 1,
  4187. + }, {
  4188. + .name = "mzk-w300nh:blue:wps",
  4189. + .gpio = MZK_W300NH_GPIO_LED_WPS,
  4190. + .active_low = 1,
  4191. + }, {
  4192. + .name = "mzk-w300nh:green:wlan",
  4193. + .gpio = MZK_W300NH_GPIO_LED_WLAN,
  4194. + .active_low = 1,
  4195. + }, {
  4196. + .name = "mzk-w300nh:green:ap",
  4197. + .gpio = MZK_W300NH_GPIO_LED_AP,
  4198. + .active_low = 1,
  4199. + }, {
  4200. + .name = "mzk-w300nh:green:router",
  4201. + .gpio = MZK_W300NH_GPIO_LED_ROUTER,
  4202. + .active_low = 1,
  4203. + }
  4204. +};
  4205. +
  4206. +static struct gpio_button mzk_w300nh_gpio_buttons[] __initdata = {
  4207. + {
  4208. + .desc = "reset",
  4209. + .type = EV_KEY,
  4210. + .code = KEY_RESTART,
  4211. + .threshold = 3,
  4212. + .gpio = MZK_W300NH_GPIO_BTN_RESET,
  4213. + .active_low = 1,
  4214. + }, {
  4215. + .desc = "wps",
  4216. + .type = EV_KEY,
  4217. + .code = KEY_WPS_BUTTON,
  4218. + .threshold = 3,
  4219. + .gpio = MZK_W300NH_GPIO_BTN_WPS,
  4220. + .active_low = 1,
  4221. + }, {
  4222. + .desc = "aprouter",
  4223. + .type = EV_KEY,
  4224. + .code = BTN_2,
  4225. + .threshold = 3,
  4226. + .gpio = MZK_W300NH_GPIO_BTN_APROUTER,
  4227. + .active_low = 0,
  4228. + }
  4229. +};
  4230. +
  4231. +#define MZK_W300NH_WAN_PHYMASK BIT(4)
  4232. +#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK)
  4233. +
  4234. +static void __init mzk_w300nh_setup(void)
  4235. +{
  4236. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4237. +
  4238. + ar71xx_set_mac_base(eeprom);
  4239. +
  4240. + ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK);
  4241. +
  4242. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4243. + ar71xx_eth0_data.speed = SPEED_100;
  4244. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4245. + ar71xx_eth0_data.has_ar8216 = 1;
  4246. +
  4247. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4248. + ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK;
  4249. +
  4250. + ar71xx_add_device_eth(0);
  4251. + ar71xx_add_device_eth(1);
  4252. +
  4253. + ar71xx_add_device_m25p80(&mzk_w300nh_flash_data);
  4254. +
  4255. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio),
  4256. + mzk_w300nh_leds_gpio);
  4257. +
  4258. + ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
  4259. + ARRAY_SIZE(mzk_w300nh_gpio_buttons),
  4260. + mzk_w300nh_gpio_buttons);
  4261. + ar913x_add_device_wmac(eeprom, NULL);
  4262. +}
  4263. +
  4264. +MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH",
  4265. + mzk_w300nh_setup);
  4266. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.37/arch/mips/ar71xx/mach-nbg460n.c
  4267. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100
  4268. +++ linux-2.6.37/arch/mips/ar71xx/mach-nbg460n.c 2011-01-11 20:25:48.000000000 +0100
  4269. @@ -0,0 +1,222 @@
  4270. +/*
  4271. + * Zyxel NBG 460N/550N/550NH board support
  4272. + *
  4273. + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
  4274. + *
  4275. + * based on mach-tl-wr1043nd.c
  4276. + *
  4277. + * This program is free software; you can redistribute it and/or modify it
  4278. + * under the terms of the GNU General Public License version 2 as published
  4279. + * by the Free Software Foundation.
  4280. + */
  4281. +
  4282. +#include <linux/platform_device.h>
  4283. +#include <linux/mtd/mtd.h>
  4284. +#include <linux/mtd/partitions.h>
  4285. +#include <linux/delay.h>
  4286. +#include <linux/rtl8366s.h>
  4287. +
  4288. +#include <linux/i2c.h>
  4289. +#include <linux/i2c-algo-bit.h>
  4290. +#include <linux/i2c-gpio.h>
  4291. +
  4292. +#include <asm/mach-ar71xx/ar71xx.h>
  4293. +
  4294. +#include "machtype.h"
  4295. +#include "devices.h"
  4296. +#include "dev-m25p80.h"
  4297. +#include "dev-ar913x-wmac.h"
  4298. +#include "dev-gpio-buttons.h"
  4299. +#include "dev-leds-gpio.h"
  4300. +
  4301. +/* LEDs */
  4302. +#define NBG460N_GPIO_LED_WPS 3
  4303. +#define NBG460N_GPIO_LED_WAN 6
  4304. +#define NBG460N_GPIO_LED_POWER 14
  4305. +#define NBG460N_GPIO_LED_WLAN 15
  4306. +
  4307. +/* Buttons */
  4308. +#define NBG460N_GPIO_BTN_WPS 12
  4309. +#define NBG460N_GPIO_BTN_RESET 21
  4310. +#define NBG460N_BUTTONS_POLL_INTERVAL 20
  4311. +
  4312. +/* RTC chip PCF8563 I2C interface */
  4313. +#define NBG460N_GPIO_PCF8563_SDA 8
  4314. +#define NBG460N_GPIO_PCF8563_SCK 7
  4315. +
  4316. +/* Switch configuration I2C interface */
  4317. +#define NBG460N_GPIO_RTL8366_SDA 16
  4318. +#define NBG460N_GPIO_RTL8366_SCK 18
  4319. +
  4320. +#ifdef CONFIG_MTD_PARTITIONS
  4321. +static struct mtd_partition nbg460n_partitions[] = {
  4322. + {
  4323. + .name = "Bootbase",
  4324. + .offset = 0,
  4325. + .size = 0x010000,
  4326. + .mask_flags = MTD_WRITEABLE,
  4327. + } , {
  4328. + .name = "U-Boot Config",
  4329. + .offset = 0x010000,
  4330. + .size = 0x030000,
  4331. + } , {
  4332. + .name = "U-Boot",
  4333. + .offset = 0x040000,
  4334. + .size = 0x030000,
  4335. + } , {
  4336. + .name = "linux",
  4337. + .offset = 0x070000,
  4338. + .size = 0x0e0000,
  4339. + } , {
  4340. + .name = "rootfs",
  4341. + .offset = 0x150000,
  4342. + .size = 0x2a0000,
  4343. + } , {
  4344. + .name = "CalibData",
  4345. + .offset = 0x3f0000,
  4346. + .size = 0x010000,
  4347. + .mask_flags = MTD_WRITEABLE,
  4348. + } , {
  4349. + .name = "firmware",
  4350. + .offset = 0x070000,
  4351. + .size = 0x380000,
  4352. + }
  4353. +};
  4354. +#endif /* CONFIG_MTD_PARTITIONS */
  4355. +
  4356. +static struct flash_platform_data nbg460n_flash_data = {
  4357. +#ifdef CONFIG_MTD_PARTITIONS
  4358. + .parts = nbg460n_partitions,
  4359. + .nr_parts = ARRAY_SIZE(nbg460n_partitions),
  4360. +#endif
  4361. +};
  4362. +
  4363. +static struct gpio_led nbg460n_leds_gpio[] __initdata = {
  4364. + {
  4365. + .name = "nbg460n:green:power",
  4366. + .gpio = NBG460N_GPIO_LED_POWER,
  4367. + .active_low = 0,
  4368. + .default_trigger = "default-on",
  4369. + }, {
  4370. + .name = "nbg460n:green:wps",
  4371. + .gpio = NBG460N_GPIO_LED_WPS,
  4372. + .active_low = 0,
  4373. + }, {
  4374. + .name = "nbg460n:green:wlan",
  4375. + .gpio = NBG460N_GPIO_LED_WLAN,
  4376. + .active_low = 0,
  4377. + }, {
  4378. + /* Not really for controlling the LED,
  4379. + when set low the LED blinks uncontrollable */
  4380. + .name = "nbg460n:green:wan",
  4381. + .gpio = NBG460N_GPIO_LED_WAN,
  4382. + .active_low = 0,
  4383. + }
  4384. +};
  4385. +
  4386. +static struct gpio_button nbg460n_gpio_buttons[] __initdata = {
  4387. + {
  4388. + .desc = "reset",
  4389. + .type = EV_KEY,
  4390. + .code = KEY_RESTART,
  4391. + .threshold = 3,
  4392. + .gpio = NBG460N_GPIO_BTN_RESET,
  4393. + .active_low = 1,
  4394. + }, {
  4395. + .desc = "wps",
  4396. + .type = EV_KEY,
  4397. + .code = KEY_WPS_BUTTON,
  4398. + .threshold = 3,
  4399. + .gpio = NBG460N_GPIO_BTN_WPS,
  4400. + .active_low = 1,
  4401. + }
  4402. +};
  4403. +
  4404. +static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = {
  4405. + .sda_pin = NBG460N_GPIO_PCF8563_SDA,
  4406. + .scl_pin = NBG460N_GPIO_PCF8563_SCK,
  4407. + .udelay = 10,
  4408. +};
  4409. +
  4410. +static struct platform_device nbg460n_i2c_device = {
  4411. + .name = "i2c-gpio",
  4412. + .id = -1,
  4413. + .num_resources = 0,
  4414. + .resource = NULL,
  4415. + .dev = {
  4416. + .platform_data = &nbg460n_i2c_device_platdata,
  4417. + },
  4418. +};
  4419. +
  4420. +static struct i2c_board_info nbg460n_i2c_devs[] __initdata = {
  4421. + {
  4422. + I2C_BOARD_INFO("pcf8563", 0x51),
  4423. + },
  4424. +};
  4425. +
  4426. +static void __devinit nbg460n_i2c_init(void)
  4427. +{
  4428. + /* The gpio interface */
  4429. + platform_device_register(&nbg460n_i2c_device);
  4430. + /* I2C devices */
  4431. + i2c_register_board_info(0, nbg460n_i2c_devs,
  4432. + ARRAY_SIZE(nbg460n_i2c_devs));
  4433. +}
  4434. +
  4435. +
  4436. +static struct rtl8366s_platform_data nbg460n_rtl8366s_data = {
  4437. + .gpio_sda = NBG460N_GPIO_RTL8366_SDA,
  4438. + .gpio_sck = NBG460N_GPIO_RTL8366_SCK,
  4439. +};
  4440. +
  4441. +static struct platform_device nbg460n_rtl8366s_device = {
  4442. + .name = RTL8366S_DRIVER_NAME,
  4443. + .id = -1,
  4444. + .dev = {
  4445. + .platform_data = &nbg460n_rtl8366s_data,
  4446. + }
  4447. +};
  4448. +
  4449. +static void __init nbg460n_setup(void)
  4450. +{
  4451. + /* end of bootloader sector contains mac address*/
  4452. + u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8);
  4453. + /* last sector contains wlan calib data */
  4454. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  4455. +
  4456. + ar71xx_set_mac_base(mac);
  4457. +
  4458. + /* LAN Port */
  4459. + ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4460. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4461. + ar71xx_eth0_data.speed = SPEED_1000;
  4462. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4463. +
  4464. + /* WAN Port */
  4465. + ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev;
  4466. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4467. + ar71xx_eth1_data.phy_mask = 0x10;
  4468. +
  4469. + ar71xx_add_device_eth(0);
  4470. + ar71xx_add_device_eth(1);
  4471. +
  4472. + /* register the switch phy */
  4473. + platform_device_register(&nbg460n_rtl8366s_device);
  4474. +
  4475. + /* register flash */
  4476. + ar71xx_add_device_m25p80(&nbg460n_flash_data);
  4477. +
  4478. + ar913x_add_device_wmac(eeprom, mac);
  4479. +
  4480. + /* register RTC chip */
  4481. + nbg460n_i2c_init();
  4482. +
  4483. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio),
  4484. + nbg460n_leds_gpio);
  4485. +
  4486. + ar71xx_add_device_gpio_buttons(-1, NBG460N_BUTTONS_POLL_INTERVAL,
  4487. + ARRAY_SIZE(nbg460n_gpio_buttons),
  4488. + nbg460n_gpio_buttons);
  4489. +}
  4490. +
  4491. +MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", nbg460n_setup);
  4492. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.37/arch/mips/ar71xx/mach-pb42.c
  4493. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100
  4494. +++ linux-2.6.37/arch/mips/ar71xx/mach-pb42.c 2011-01-11 20:25:48.000000000 +0100
  4495. @@ -0,0 +1,71 @@
  4496. +/*
  4497. + * Atheros PB42 board support
  4498. + *
  4499. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4500. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4501. + *
  4502. + * This program is free software; you can redistribute it and/or modify it
  4503. + * under the terms of the GNU General Public License version 2 as published
  4504. + * by the Free Software Foundation.
  4505. + */
  4506. +
  4507. +#include <asm/mach-ar71xx/ar71xx.h>
  4508. +
  4509. +#include "machtype.h"
  4510. +#include "devices.h"
  4511. +#include "dev-m25p80.h"
  4512. +#include "dev-gpio-buttons.h"
  4513. +#include "dev-pb42-pci.h"
  4514. +#include "dev-usb.h"
  4515. +
  4516. +#define PB42_BUTTONS_POLL_INTERVAL 20
  4517. +
  4518. +#define PB42_GPIO_BTN_SW4 8
  4519. +#define PB42_GPIO_BTN_SW5 3
  4520. +
  4521. +static struct gpio_button pb42_gpio_buttons[] __initdata = {
  4522. + {
  4523. + .desc = "sw4",
  4524. + .type = EV_KEY,
  4525. + .code = BTN_0,
  4526. + .threshold = 3,
  4527. + .gpio = PB42_GPIO_BTN_SW4,
  4528. + .active_low = 1,
  4529. + } , {
  4530. + .desc = "sw5",
  4531. + .type = EV_KEY,
  4532. + .code = BTN_1,
  4533. + .threshold = 3,
  4534. + .gpio = PB42_GPIO_BTN_SW5,
  4535. + .active_low = 1,
  4536. + }
  4537. +};
  4538. +
  4539. +#define PB42_WAN_PHYMASK BIT(20)
  4540. +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19))
  4541. +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
  4542. +
  4543. +static void __init pb42_init(void)
  4544. +{
  4545. + ar71xx_add_device_m25p80(NULL);
  4546. +
  4547. + ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
  4548. +
  4549. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  4550. + ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
  4551. +
  4552. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4553. + ar71xx_eth1_data.speed = SPEED_100;
  4554. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4555. +
  4556. + ar71xx_add_device_eth(0);
  4557. + ar71xx_add_device_eth(1);
  4558. +
  4559. + ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL,
  4560. + ARRAY_SIZE(pb42_gpio_buttons),
  4561. + pb42_gpio_buttons);
  4562. +
  4563. + pb42_pci_init();
  4564. +}
  4565. +
  4566. +MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init);
  4567. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.37/arch/mips/ar71xx/mach-pb44.c
  4568. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100
  4569. +++ linux-2.6.37/arch/mips/ar71xx/mach-pb44.c 2011-01-11 20:25:48.000000000 +0100
  4570. @@ -0,0 +1,207 @@
  4571. +/*
  4572. + * Atheros PB44 board support
  4573. + *
  4574. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  4575. + *
  4576. + * This program is free software; you can redistribute it and/or modify it
  4577. + * under the terms of the GNU General Public License version 2 as published
  4578. + * by the Free Software Foundation.
  4579. + */
  4580. +
  4581. +#include <linux/init.h>
  4582. +#include <linux/bitops.h>
  4583. +#include <linux/delay.h>
  4584. +#include <linux/platform_device.h>
  4585. +#include <linux/spi/spi.h>
  4586. +#include <linux/spi/flash.h>
  4587. +#include <linux/spi/vsc7385.h>
  4588. +#include <linux/i2c.h>
  4589. +#include <linux/i2c-gpio.h>
  4590. +#include <linux/i2c/pcf857x.h>
  4591. +
  4592. +#include <asm/mach-ar71xx/ar71xx.h>
  4593. +
  4594. +#include "machtype.h"
  4595. +#include "devices.h"
  4596. +#include "dev-pb42-pci.h"
  4597. +#include "dev-gpio-buttons.h"
  4598. +#include "dev-leds-gpio.h"
  4599. +#include "dev-usb.h"
  4600. +
  4601. +#define PB44_PCF8757_VSC7395_CS 0
  4602. +#define PB44_PCF8757_STEREO_CS 1
  4603. +#define PB44_PCF8757_SLIC_CS0 2
  4604. +#define PB44_PCF8757_SLIC_TEST 3
  4605. +#define PB44_PCF8757_SLIC_INT0 4
  4606. +#define PB44_PCF8757_SLIC_INT1 5
  4607. +#define PB44_PCF8757_SW_RESET 6
  4608. +#define PB44_PCF8757_SW_JUMP 8
  4609. +#define PB44_PCF8757_LED_JUMP1 9
  4610. +#define PB44_PCF8757_LED_JUMP2 10
  4611. +#define PB44_PCF8757_TP24 11
  4612. +#define PB44_PCF8757_TP25 12
  4613. +#define PB44_PCF8757_TP26 13
  4614. +#define PB44_PCF8757_TP27 14
  4615. +#define PB44_PCF8757_TP28 15
  4616. +
  4617. +#define PB44_GPIO_I2C_SCL 0
  4618. +#define PB44_GPIO_I2C_SDA 1
  4619. +
  4620. +#define PB44_GPIO_EXP_BASE 16
  4621. +#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS)
  4622. +#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET)
  4623. +#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP)
  4624. +#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1)
  4625. +#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2)
  4626. +
  4627. +static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
  4628. + .sda_pin = PB44_GPIO_I2C_SDA,
  4629. + .scl_pin = PB44_GPIO_I2C_SCL,
  4630. +};
  4631. +
  4632. +static struct platform_device pb44_i2c_gpio_device = {
  4633. + .name = "i2c-gpio",
  4634. + .id = 0,
  4635. + .dev = {
  4636. + .platform_data = &pb44_i2c_gpio_data,
  4637. + }
  4638. +};
  4639. +
  4640. +static struct pcf857x_platform_data pb44_pcf857x_data = {
  4641. + .gpio_base = PB44_GPIO_EXP_BASE,
  4642. +};
  4643. +
  4644. +static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
  4645. + {
  4646. + I2C_BOARD_INFO("pcf8575", 0x20),
  4647. + .platform_data = &pb44_pcf857x_data,
  4648. + },
  4649. +};
  4650. +
  4651. +static struct gpio_led pb44_leds_gpio[] __initdata = {
  4652. + {
  4653. + .name = "pb44:amber:jump1",
  4654. + .gpio = PB44_GPIO_LED_JUMP1,
  4655. + .active_low = 1,
  4656. + }, {
  4657. + .name = "pb44:green:jump2",
  4658. + .gpio = PB44_GPIO_LED_JUMP2,
  4659. + .active_low = 1,
  4660. + },
  4661. +};
  4662. +
  4663. +static struct gpio_button pb44_gpio_buttons[] __initdata = {
  4664. + {
  4665. + .desc = "soft_reset",
  4666. + .type = EV_KEY,
  4667. + .code = KEY_RESTART,
  4668. + .threshold = 3,
  4669. + .gpio = PB44_GPIO_SW_RESET,
  4670. + .active_low = 1,
  4671. + } , {
  4672. + .desc = "jumpstart",
  4673. + .type = EV_KEY,
  4674. + .code = KEY_WPS_BUTTON,
  4675. + .threshold = 3,
  4676. + .gpio = PB44_GPIO_SW_JUMP,
  4677. + .active_low = 1,
  4678. + }
  4679. +};
  4680. +
  4681. +static void pb44_vsc7395_reset(void)
  4682. +{
  4683. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  4684. + udelay(10);
  4685. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  4686. + mdelay(50);
  4687. +}
  4688. +
  4689. +static struct vsc7385_platform_data pb44_vsc7395_data = {
  4690. + .reset = pb44_vsc7395_reset,
  4691. + .ucode_name = "vsc7395_ucode_pb44.bin",
  4692. + .mac_cfg = {
  4693. + .tx_ipg = 6,
  4694. + .bit2 = 1,
  4695. + .clk_sel = 0,
  4696. + },
  4697. +};
  4698. +
  4699. +static struct spi_board_info pb44_spi_info[] = {
  4700. + {
  4701. + .bus_num = 0,
  4702. + .chip_select = 0,
  4703. + .max_speed_hz = 25000000,
  4704. + .modalias = "m25p80",
  4705. + }, {
  4706. + .bus_num = 0,
  4707. + .chip_select = 1,
  4708. + .max_speed_hz = 25000000,
  4709. + .modalias = "spi-vsc7385",
  4710. + .platform_data = &pb44_vsc7395_data,
  4711. + .controller_data = (void *) PB44_GPIO_VSC7395_CS,
  4712. + },
  4713. +};
  4714. +
  4715. +static struct resource pb44_spi_resources[] = {
  4716. + [0] = {
  4717. + .start = AR71XX_SPI_BASE,
  4718. + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
  4719. + .flags = IORESOURCE_MEM,
  4720. + },
  4721. +};
  4722. +
  4723. +static struct ar71xx_spi_platform_data pb44_spi_data = {
  4724. + .bus_num = 0,
  4725. + .num_chipselect = 2,
  4726. +};
  4727. +
  4728. +static struct platform_device pb44_spi_device = {
  4729. + .name = "pb44-spi",
  4730. + .id = -1,
  4731. + .resource = pb44_spi_resources,
  4732. + .num_resources = ARRAY_SIZE(pb44_spi_resources),
  4733. + .dev = {
  4734. + .platform_data = &pb44_spi_data,
  4735. + },
  4736. +};
  4737. +
  4738. +#define PB44_WAN_PHYMASK BIT(0)
  4739. +#define PB44_LAN_PHYMASK 0
  4740. +#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK)
  4741. +
  4742. +static void __init pb44_init(void)
  4743. +{
  4744. + ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK);
  4745. +
  4746. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4747. + ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK;
  4748. +
  4749. + ar71xx_add_device_eth(0);
  4750. +
  4751. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  4752. + ar71xx_eth1_data.speed = SPEED_1000;
  4753. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4754. + ar71xx_eth1_pll_data.pll_1000 = 0x110000;
  4755. +
  4756. + ar71xx_add_device_eth(1);
  4757. +
  4758. + ar71xx_add_device_usb();
  4759. +
  4760. + pb42_pci_init();
  4761. +
  4762. + i2c_register_board_info(0, pb44_i2c_board_info,
  4763. + ARRAY_SIZE(pb44_i2c_board_info));
  4764. +
  4765. + platform_device_register(&pb44_i2c_gpio_device);
  4766. +
  4767. + spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info));
  4768. + platform_device_register(&pb44_spi_device);
  4769. +
  4770. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
  4771. + pb44_leds_gpio);
  4772. +
  4773. + ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(pb44_gpio_buttons),
  4774. + pb44_gpio_buttons);
  4775. +}
  4776. +
  4777. +MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init);
  4778. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.37/arch/mips/ar71xx/mach-pb92.c
  4779. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100
  4780. +++ linux-2.6.37/arch/mips/ar71xx/mach-pb92.c 2011-01-11 20:25:48.000000000 +0100
  4781. @@ -0,0 +1,109 @@
  4782. +/*
  4783. + * Atheros PB92 board support
  4784. + *
  4785. + * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
  4786. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  4787. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4788. + *
  4789. + * This program is free software; you can redistribute it and/or modify it
  4790. + * under the terms of the GNU General Public License version 2 as published
  4791. + * by the Free Software Foundation.
  4792. + */
  4793. +
  4794. +#include <linux/mtd/mtd.h>
  4795. +#include <linux/mtd/partitions.h>
  4796. +#include <asm/mach-ar71xx/ar71xx.h>
  4797. +
  4798. +#include "machtype.h"
  4799. +#include "devices.h"
  4800. +#include "dev-m25p80.h"
  4801. +#include "dev-gpio-buttons.h"
  4802. +#include "dev-pb9x-pci.h"
  4803. +#include "dev-usb.h"
  4804. +
  4805. +#ifdef CONFIG_MTD_PARTITIONS
  4806. +static struct mtd_partition pb92_partitions[] = {
  4807. + {
  4808. + .name = "u-boot",
  4809. + .offset = 0,
  4810. + .size = 0x040000,
  4811. + .mask_flags = MTD_WRITEABLE,
  4812. + } , {
  4813. + .name = "u-boot-env",
  4814. + .offset = 0x040000,
  4815. + .size = 0x010000,
  4816. + } , {
  4817. + .name = "rootfs",
  4818. + .offset = 0x050000,
  4819. + .size = 0x2b0000,
  4820. + } , {
  4821. + .name = "uImage",
  4822. + .offset = 0x300000,
  4823. + .size = 0x0e0000,
  4824. + } , {
  4825. + .name = "ART",
  4826. + .offset = 0x3e0000,
  4827. + .size = 0x020000,
  4828. + .mask_flags = MTD_WRITEABLE,
  4829. + }
  4830. +};
  4831. +#endif /* CONFIG_MTD_PARTITIONS */
  4832. +
  4833. +static struct flash_platform_data pb92_flash_data = {
  4834. +#ifdef CONFIG_MTD_PARTITIONS
  4835. + .parts = pb92_partitions,
  4836. + .nr_parts = ARRAY_SIZE(pb92_partitions),
  4837. +#endif
  4838. +};
  4839. +
  4840. +
  4841. +#define PB92_BUTTONS_POLL_INTERVAL 20
  4842. +
  4843. +#define PB92_GPIO_BTN_SW4 8
  4844. +#define PB92_GPIO_BTN_SW5 3
  4845. +
  4846. +static struct gpio_button pb92_gpio_buttons[] __initdata = {
  4847. + {
  4848. + .desc = "sw4",
  4849. + .type = EV_KEY,
  4850. + .code = BTN_0,
  4851. + .threshold = 3,
  4852. + .gpio = PB92_GPIO_BTN_SW4,
  4853. + .active_low = 1,
  4854. + } , {
  4855. + .desc = "sw5",
  4856. + .type = EV_KEY,
  4857. + .code = BTN_1,
  4858. + .threshold = 3,
  4859. + .gpio = PB92_GPIO_BTN_SW5,
  4860. + .active_low = 1,
  4861. + }
  4862. +};
  4863. +
  4864. +static void __init pb92_init(void)
  4865. +{
  4866. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  4867. +
  4868. + ar71xx_set_mac_base(mac);
  4869. + ar71xx_add_device_m25p80(&pb92_flash_data);
  4870. +
  4871. + ar71xx_add_device_mdio(~0);
  4872. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4873. + ar71xx_eth0_data.speed = SPEED_1000;
  4874. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  4875. +
  4876. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  4877. + ar71xx_eth1_data.speed = SPEED_1000;
  4878. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  4879. +
  4880. + ar71xx_add_device_eth(0);
  4881. + ar71xx_add_device_eth(1);
  4882. +
  4883. + ar71xx_add_device_gpio_buttons(-1, PB92_BUTTONS_POLL_INTERVAL,
  4884. + ARRAY_SIZE(pb92_gpio_buttons),
  4885. + pb92_gpio_buttons);
  4886. +
  4887. + pb9x_pci_init();
  4888. +}
  4889. +
  4890. +MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init);
  4891. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.37/arch/mips/ar71xx/mach-rb4xx.c
  4892. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100
  4893. +++ linux-2.6.37/arch/mips/ar71xx/mach-rb4xx.c 2011-01-11 20:25:48.000000000 +0100
  4894. @@ -0,0 +1,290 @@
  4895. +/*
  4896. + * MikroTik RouterBOARD 4xx series support
  4897. + *
  4898. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  4899. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  4900. + *
  4901. + * This program is free software; you can redistribute it and/or modify it
  4902. + * under the terms of the GNU General Public License version 2 as published
  4903. + * by the Free Software Foundation.
  4904. + */
  4905. +
  4906. +#include <linux/platform_device.h>
  4907. +#include <linux/irq.h>
  4908. +#include <linux/mmc/host.h>
  4909. +#include <linux/spi/spi.h>
  4910. +#include <linux/spi/flash.h>
  4911. +#include <linux/spi/mmc_spi.h>
  4912. +
  4913. +#include <asm/mach-ar71xx/ar71xx.h>
  4914. +#include <asm/mach-ar71xx/pci.h>
  4915. +
  4916. +#include "machtype.h"
  4917. +#include "devices.h"
  4918. +#include "dev-gpio-buttons.h"
  4919. +#include "dev-leds-gpio.h"
  4920. +#include "dev-usb.h"
  4921. +
  4922. +#define RB4XX_GPIO_USER_LED 4
  4923. +#define RB4XX_GPIO_RESET_SWITCH 7
  4924. +
  4925. +#define RB4XX_BUTTONS_POLL_INTERVAL 20
  4926. +
  4927. +static struct gpio_led rb4xx_leds_gpio[] __initdata = {
  4928. + {
  4929. + .name = "rb4xx:yellow:user",
  4930. + .gpio = RB4XX_GPIO_USER_LED,
  4931. + .active_low = 0,
  4932. + },
  4933. +};
  4934. +
  4935. +static struct gpio_button rb4xx_gpio_buttons[] __initdata = {
  4936. + {
  4937. + .desc = "reset_switch",
  4938. + .type = EV_KEY,
  4939. + .code = KEY_RESTART,
  4940. + .threshold = 3,
  4941. + .gpio = RB4XX_GPIO_RESET_SWITCH,
  4942. + .active_low = 1,
  4943. + }
  4944. +};
  4945. +
  4946. +static struct platform_device rb4xx_nand_device = {
  4947. + .name = "rb4xx-nand",
  4948. + .id = -1,
  4949. +};
  4950. +
  4951. +static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
  4952. + {
  4953. + .slot = 0,
  4954. + .pin = 1,
  4955. + .irq = AR71XX_PCI_IRQ_DEV2,
  4956. + }, {
  4957. + .slot = 1,
  4958. + .pin = 1,
  4959. + .irq = AR71XX_PCI_IRQ_DEV0,
  4960. + }, {
  4961. + .slot = 1,
  4962. + .pin = 2,
  4963. + .irq = AR71XX_PCI_IRQ_DEV1,
  4964. + }, {
  4965. + .slot = 2,
  4966. + .pin = 1,
  4967. + .irq = AR71XX_PCI_IRQ_DEV1,
  4968. + }, {
  4969. + .slot = 3,
  4970. + .pin = 1,
  4971. + .irq = AR71XX_PCI_IRQ_DEV2,
  4972. + }
  4973. +};
  4974. +
  4975. +#if 0
  4976. +/*
  4977. + * SPI device support is experimental
  4978. + */
  4979. +static struct flash_platform_data rb4xx_flash_data = {
  4980. + .type = "pm25lv512",
  4981. +};
  4982. +
  4983. +static struct spi_board_info rb4xx_spi_info[] = {
  4984. + {
  4985. + .bus_num = 0,
  4986. + .chip_select = 0,
  4987. + .max_speed_hz = 25000000,
  4988. + .modalias = "m25p80",
  4989. + .platform_data = &rb4xx_flash_data,
  4990. + }
  4991. +};
  4992. +
  4993. +static struct mmc_spi_platform_data rb433_mmc_data = {
  4994. + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
  4995. +};
  4996. +
  4997. +static struct spi_board_info rb433_spi_info[] = {
  4998. + {
  4999. + .bus_num = 0,
  5000. + .chip_select = 0,
  5001. + .max_speed_hz = 25000000,
  5002. + .modalias = "m25p80",
  5003. + .platform_data = &rb433_flash_data,
  5004. + }, {
  5005. + .bus_num = 0,
  5006. + .chip_select = 2,
  5007. + .max_speed_hz = 25000000,
  5008. + .modalias = "mmc_spi",
  5009. + .platform_data = &rb433_mmc_data,
  5010. + }
  5011. +};
  5012. +
  5013. +static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  5014. +{
  5015. + u32 ret;
  5016. +
  5017. + if (is_on == AR71XX_SPI_CS_INACTIVE) {
  5018. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5019. + } else {
  5020. + if (cs_high) {
  5021. + ret = SPI_IOC_CS0 | SPI_IOC_CS1;
  5022. + } else {
  5023. + if ((chip_select ^ 2) == 0)
  5024. + ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5025. + else
  5026. + ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
  5027. + }
  5028. + }
  5029. +
  5030. + return ret;
  5031. +}
  5032. +
  5033. +struct ar71xx_spi_platform_data rb433_spi_data = {
  5034. + .bus_num = 0,
  5035. + .num_chipselect = 3,
  5036. + .get_ioc_base = rb433_spi_get_ioc_base,
  5037. +};
  5038. +
  5039. +static void rb4xx_add_device_spi(void)
  5040. +{
  5041. + ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
  5042. +}
  5043. +
  5044. +static void rb433_add_device_spi(void)
  5045. +{
  5046. + ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info,
  5047. + ARRAY_SIZE(rb433_spi_info));
  5048. +}
  5049. +#else
  5050. +static inline void rb4xx_add_device_spi(void) {}
  5051. +static inline void rb433_add_device_spi(void) {}
  5052. +#endif
  5053. +
  5054. +static void __init rb4xx_generic_setup(void)
  5055. +{
  5056. + ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN |
  5057. + AR71XX_GPIO_FUNC_SPI_CS2_EN);
  5058. +
  5059. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
  5060. + rb4xx_leds_gpio);
  5061. +
  5062. + ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL,
  5063. + ARRAY_SIZE(rb4xx_gpio_buttons),
  5064. + rb4xx_gpio_buttons);
  5065. +
  5066. + platform_device_register(&rb4xx_nand_device);
  5067. +}
  5068. +
  5069. +static void __init rb411_setup(void)
  5070. +{
  5071. + rb4xx_generic_setup();
  5072. + rb4xx_add_device_spi();
  5073. +
  5074. + ar71xx_add_device_mdio(0xfffffffc);
  5075. +
  5076. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5077. + ar71xx_eth0_data.phy_mask = 0x00000003;
  5078. +
  5079. + ar71xx_add_device_eth(0);
  5080. +
  5081. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5082. +}
  5083. +
  5084. +MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH",
  5085. + rb411_setup);
  5086. +
  5087. +static void __init rb411u_setup(void)
  5088. +{
  5089. + rb411_setup();
  5090. + ar71xx_add_device_usb();
  5091. +}
  5092. +
  5093. +MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U",
  5094. + rb411u_setup);
  5095. +
  5096. +static void __init rb433_setup(void)
  5097. +{
  5098. + rb4xx_generic_setup();
  5099. + rb433_add_device_spi();
  5100. +
  5101. + ar71xx_add_device_mdio(0xffffffe9);
  5102. +
  5103. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5104. + ar71xx_eth0_data.speed = SPEED_100;
  5105. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5106. +
  5107. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5108. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5109. +
  5110. + ar71xx_add_device_eth(1);
  5111. + ar71xx_add_device_eth(0);
  5112. +
  5113. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5114. +}
  5115. +
  5116. +MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH",
  5117. + rb433_setup);
  5118. +
  5119. +static void __init rb433u_setup(void)
  5120. +{
  5121. + rb433_setup();
  5122. + ar71xx_add_device_usb();
  5123. +}
  5124. +
  5125. +MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH",
  5126. + rb433u_setup);
  5127. +
  5128. +static void __init rb450_generic_setup(int gige)
  5129. +{
  5130. + rb4xx_generic_setup();
  5131. + rb4xx_add_device_spi();
  5132. +
  5133. + ar71xx_add_device_mdio(0xffffffe0);
  5134. +
  5135. + ar71xx_eth0_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII;
  5136. + ar71xx_eth0_data.phy_mask = (gige) ? (1 << 0) : 0;
  5137. + ar71xx_eth0_data.speed = (gige) ? SPEED_1000 : SPEED_100;
  5138. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5139. +
  5140. + ar71xx_eth1_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII;
  5141. + ar71xx_eth1_data.phy_mask = 0x00000010;
  5142. +
  5143. + ar71xx_add_device_eth(1);
  5144. + ar71xx_add_device_eth(0);
  5145. +}
  5146. +
  5147. +static void __init rb450_setup(void)
  5148. +{
  5149. + rb450_generic_setup(0);
  5150. +}
  5151. +
  5152. +MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450",
  5153. + rb450_setup);
  5154. +
  5155. +static void __init rb450g_setup(void)
  5156. +{
  5157. + rb450_generic_setup(1);
  5158. +}
  5159. +
  5160. +MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G",
  5161. + rb450g_setup);
  5162. +
  5163. +static void __init rb493_setup(void)
  5164. +{
  5165. + rb4xx_generic_setup();
  5166. + rb4xx_add_device_spi();
  5167. +
  5168. + ar71xx_add_device_mdio(0x3fffff00);
  5169. +
  5170. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  5171. + ar71xx_eth0_data.speed = SPEED_100;
  5172. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5173. +
  5174. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5175. + ar71xx_eth1_data.phy_mask = 0x00000001;
  5176. +
  5177. + ar71xx_add_device_eth(0);
  5178. + ar71xx_add_device_eth(1);
  5179. +
  5180. + ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
  5181. +}
  5182. +
  5183. +MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH",
  5184. + rb493_setup);
  5185. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.37/arch/mips/ar71xx/mach-rb750.c
  5186. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100
  5187. +++ linux-2.6.37/arch/mips/ar71xx/mach-rb750.c 2011-01-11 20:25:48.000000000 +0100
  5188. @@ -0,0 +1,133 @@
  5189. +/*
  5190. + * MikroTik RouterBOARD 750 support
  5191. + *
  5192. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  5193. + *
  5194. + * This program is free software; you can redistribute it and/or modify it
  5195. + * under the terms of the GNU General Public License version 2 as published
  5196. + * by the Free Software Foundation.
  5197. + */
  5198. +
  5199. +#include <linux/platform_device.h>
  5200. +#include <asm/mach-ar71xx/ar71xx.h>
  5201. +#include <asm/mach-ar71xx/mach-rb750.h>
  5202. +
  5203. +#include "machtype.h"
  5204. +#include "dev-ap91-eth.h"
  5205. +
  5206. +static struct rb750_led_data rb750_leds[] = {
  5207. + {
  5208. + .name = "rb750:green:act",
  5209. + .mask = RB750_LED_ACT,
  5210. + .active_low = 1,
  5211. + }, {
  5212. + .name = "rb750:green:port1",
  5213. + .mask = RB750_LED_PORT5,
  5214. + .active_low = 1,
  5215. + }, {
  5216. + .name = "rb750:green:port2",
  5217. + .mask = RB750_LED_PORT4,
  5218. + .active_low = 1,
  5219. + }, {
  5220. + .name = "rb750:green:port3",
  5221. + .mask = RB750_LED_PORT3,
  5222. + .active_low = 1,
  5223. + }, {
  5224. + .name = "rb750:green:port4",
  5225. + .mask = RB750_LED_PORT2,
  5226. + .active_low = 1,
  5227. + }, {
  5228. + .name = "rb750:green:port5",
  5229. + .mask = RB750_LED_PORT1,
  5230. + .active_low = 1,
  5231. + }
  5232. +};
  5233. +
  5234. +static struct rb750_led_platform_data rb750_leds_data = {
  5235. + .num_leds = ARRAY_SIZE(rb750_leds),
  5236. + .leds = rb750_leds,
  5237. +};
  5238. +
  5239. +static struct platform_device rb750_leds_device = {
  5240. + .name = "leds-rb750",
  5241. + .dev = {
  5242. + .platform_data = &rb750_leds_data,
  5243. + }
  5244. +};
  5245. +
  5246. +static const char *rb750_port_names[AP91_ETH_NUM_PORT_NAMES] __initdata = {
  5247. + "port5",
  5248. + "port4",
  5249. + "port3",
  5250. + "port2",
  5251. +};
  5252. +
  5253. +static struct platform_device rb750_nand_device = {
  5254. + .name = "rb750-nand",
  5255. + .id = -1,
  5256. +};
  5257. +
  5258. +int rb750_latch_change(u32 mask_clr, u32 mask_set)
  5259. +{
  5260. + static DEFINE_SPINLOCK(lock);
  5261. + static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE;
  5262. + static u32 latch_oe;
  5263. + static u32 latch_clr;
  5264. + unsigned long flags;
  5265. + u32 t;
  5266. + int ret = 0;
  5267. +
  5268. + spin_lock_irqsave(&lock, flags);
  5269. +
  5270. + if ((mask_clr & BIT(31)) != 0 &&
  5271. + (latch_set & RB750_LVC573_LE) == 0) {
  5272. + goto unlock;
  5273. + }
  5274. +
  5275. + latch_set = (latch_set | mask_set) & ~mask_clr;
  5276. + latch_clr = (latch_clr | mask_clr) & ~mask_set;
  5277. +
  5278. + if (latch_oe == 0)
  5279. + latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE);
  5280. +
  5281. + if (likely(latch_set & RB750_LVC573_LE)) {
  5282. + void __iomem *base = ar71xx_gpio_base;
  5283. +
  5284. + t = __raw_readl(base + GPIO_REG_OE);
  5285. + t |= mask_clr | latch_oe | mask_set;
  5286. +
  5287. + __raw_writel(t, base + GPIO_REG_OE);
  5288. + __raw_writel(latch_clr, base + GPIO_REG_CLEAR);
  5289. + __raw_writel(latch_set, base + GPIO_REG_SET);
  5290. + } else if (mask_clr & RB750_LVC573_LE) {
  5291. + void __iomem *base = ar71xx_gpio_base;
  5292. +
  5293. + latch_oe = __raw_readl(base + GPIO_REG_OE);
  5294. + __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR);
  5295. + /* flush write */
  5296. + __raw_readl(base + GPIO_REG_CLEAR);
  5297. + }
  5298. +
  5299. + ret = 1;
  5300. +
  5301. + unlock:
  5302. + spin_unlock_irqrestore(&lock, flags);
  5303. + return ret;
  5304. +}
  5305. +EXPORT_SYMBOL_GPL(rb750_latch_change);
  5306. +
  5307. +static void __init rb750_setup(void)
  5308. +{
  5309. + ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
  5310. + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
  5311. + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
  5312. + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
  5313. + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
  5314. +
  5315. + ap91_eth_init(NULL, rb750_port_names);
  5316. + platform_device_register(&rb750_leds_device);
  5317. + platform_device_register(&rb750_nand_device);
  5318. +}
  5319. +
  5320. +MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750",
  5321. + rb750_setup);
  5322. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.37/arch/mips/ar71xx/mach-tew-632brp.c
  5323. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100
  5324. +++ linux-2.6.37/arch/mips/ar71xx/mach-tew-632brp.c 2011-01-11 20:25:48.000000000 +0100
  5325. @@ -0,0 +1,149 @@
  5326. +/*
  5327. + * TrendNET TEW-632BRP board support
  5328. + *
  5329. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  5330. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  5331. + *
  5332. + * This program is free software; you can redistribute it and/or modify it
  5333. + * under the terms of the GNU General Public License version 2 as published
  5334. + * by the Free Software Foundation.
  5335. + */
  5336. +
  5337. +#include <linux/mtd/mtd.h>
  5338. +#include <linux/mtd/partitions.h>
  5339. +
  5340. +#include <asm/mach-ar71xx/ar71xx.h>
  5341. +
  5342. +#include "machtype.h"
  5343. +#include "devices.h"
  5344. +#include "dev-m25p80.h"
  5345. +#include "dev-ar913x-wmac.h"
  5346. +#include "dev-gpio-buttons.h"
  5347. +#include "dev-leds-gpio.h"
  5348. +#include "nvram.h"
  5349. +
  5350. +#define TEW_632BRP_GPIO_LED_STATUS 1
  5351. +#define TEW_632BRP_GPIO_LED_WPS 3
  5352. +#define TEW_632BRP_GPIO_LED_WLAN 6
  5353. +#define TEW_632BRP_GPIO_BTN_WPS 12
  5354. +#define TEW_632BRP_GPIO_BTN_RESET 21
  5355. +
  5356. +#define TEW_632BRP_BUTTONS_POLL_INTERVAL 20
  5357. +
  5358. +#define TEW_632BRP_CONFIG_ADDR 0x1f020000
  5359. +#define TEW_632BRP_CONFIG_SIZE 0x10000
  5360. +
  5361. +#ifdef CONFIG_MTD_PARTITIONS
  5362. +static struct mtd_partition tew_632brp_partitions[] = {
  5363. + {
  5364. + .name = "u-boot",
  5365. + .offset = 0,
  5366. + .size = 0x020000,
  5367. + .mask_flags = MTD_WRITEABLE,
  5368. + } , {
  5369. + .name = "config",
  5370. + .offset = 0x020000,
  5371. + .size = 0x010000,
  5372. + } , {
  5373. + .name = "kernel",
  5374. + .offset = 0x030000,
  5375. + .size = 0x0d0000,
  5376. + } , {
  5377. + .name = "rootfs",
  5378. + .offset = 0x100000,
  5379. + .size = 0x2f0000,
  5380. + } , {
  5381. + .name = "art",
  5382. + .offset = 0x3f0000,
  5383. + .size = 0x010000,
  5384. + .mask_flags = MTD_WRITEABLE,
  5385. + } , {
  5386. + .name = "firmware",
  5387. + .offset = 0x030000,
  5388. + .size = 0x3c0000,
  5389. + }
  5390. +};
  5391. +#endif /* CONFIG_MTD_PARTITIONS */
  5392. +
  5393. +static struct flash_platform_data tew_632brp_flash_data = {
  5394. +#ifdef CONFIG_MTD_PARTITIONS
  5395. + .parts = tew_632brp_partitions,
  5396. + .nr_parts = ARRAY_SIZE(tew_632brp_partitions),
  5397. +#endif
  5398. +};
  5399. +
  5400. +static struct gpio_led tew_632brp_leds_gpio[] __initdata = {
  5401. + {
  5402. + .name = "tew-632brp:green:status",
  5403. + .gpio = TEW_632BRP_GPIO_LED_STATUS,
  5404. + .active_low = 1,
  5405. + }, {
  5406. + .name = "tew-632brp:blue:wps",
  5407. + .gpio = TEW_632BRP_GPIO_LED_WPS,
  5408. + .active_low = 1,
  5409. + }, {
  5410. + .name = "tew-632brp:green:wlan",
  5411. + .gpio = TEW_632BRP_GPIO_LED_WLAN,
  5412. + .active_low = 1,
  5413. + }
  5414. +};
  5415. +
  5416. +static struct gpio_button tew_632brp_gpio_buttons[] __initdata = {
  5417. + {
  5418. + .desc = "reset",
  5419. + .type = EV_KEY,
  5420. + .code = KEY_RESTART,
  5421. + .threshold = 3,
  5422. + .gpio = TEW_632BRP_GPIO_BTN_RESET,
  5423. + }, {
  5424. + .desc = "wps",
  5425. + .type = EV_KEY,
  5426. + .code = KEY_WPS_BUTTON,
  5427. + .threshold = 3,
  5428. + .gpio = TEW_632BRP_GPIO_BTN_WPS,
  5429. + }
  5430. +};
  5431. +
  5432. +#define TEW_632BRP_LAN_PHYMASK BIT(0)
  5433. +#define TEW_632BRP_WAN_PHYMASK BIT(4)
  5434. +#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \
  5435. + TEW_632BRP_WAN_PHYMASK))
  5436. +
  5437. +static void __init tew_632brp_setup(void)
  5438. +{
  5439. + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR);
  5440. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5441. + u8 mac[6];
  5442. + u8 *wlan_mac = NULL;
  5443. +
  5444. + if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE,
  5445. + "lan_mac=", mac) == 0) {
  5446. + ar71xx_set_mac_base(mac);
  5447. + wlan_mac = mac;
  5448. + }
  5449. +
  5450. + ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK);
  5451. +
  5452. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5453. + ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK;
  5454. +
  5455. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5456. + ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK;
  5457. +
  5458. + ar71xx_add_device_eth(0);
  5459. + ar71xx_add_device_eth(1);
  5460. +
  5461. + ar71xx_add_device_m25p80(&tew_632brp_flash_data);
  5462. +
  5463. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio),
  5464. + tew_632brp_leds_gpio);
  5465. +
  5466. + ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL,
  5467. + ARRAY_SIZE(tew_632brp_gpio_buttons),
  5468. + tew_632brp_gpio_buttons);
  5469. +
  5470. + ar913x_add_device_wmac(eeprom, wlan_mac);
  5471. +}
  5472. +
  5473. +MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP",
  5474. + tew_632brp_setup);
  5475. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.37/arch/mips/ar71xx/mach-tl-wr1043nd.c
  5476. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100
  5477. +++ linux-2.6.37/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-01-11 20:25:48.000000000 +0100
  5478. @@ -0,0 +1,156 @@
  5479. +/*
  5480. + * TP-LINK TL-WR1043ND board support
  5481. + *
  5482. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5483. + *
  5484. + * This program is free software; you can redistribute it and/or modify it
  5485. + * under the terms of the GNU General Public License version 2 as published
  5486. + * by the Free Software Foundation.
  5487. + */
  5488. +
  5489. +#include <linux/mtd/mtd.h>
  5490. +#include <linux/mtd/partitions.h>
  5491. +#include <linux/platform_device.h>
  5492. +#include <linux/rtl8366rb.h>
  5493. +#include <asm/mach-ar71xx/ar71xx.h>
  5494. +
  5495. +#include "machtype.h"
  5496. +#include "devices.h"
  5497. +#include "dev-m25p80.h"
  5498. +#include "dev-ar913x-wmac.h"
  5499. +#include "dev-gpio-buttons.h"
  5500. +#include "dev-leds-gpio.h"
  5501. +#include "dev-usb.h"
  5502. +
  5503. +#define TL_WR1043ND_GPIO_LED_USB 1
  5504. +#define TL_WR1043ND_GPIO_LED_SYSTEM 2
  5505. +#define TL_WR1043ND_GPIO_LED_QSS 5
  5506. +#define TL_WR1043ND_GPIO_LED_WLAN 9
  5507. +
  5508. +#define TL_WR1043ND_GPIO_BTN_RESET 3
  5509. +#define TL_WR1043ND_GPIO_BTN_QSS 7
  5510. +
  5511. +#define TL_WR1043ND_GPIO_RTL8366_SDA 18
  5512. +#define TL_WR1043ND_GPIO_RTL8366_SCK 19
  5513. +
  5514. +#define TL_WR1043ND_BUTTONS_POLL_INTERVAL 20
  5515. +
  5516. +#ifdef CONFIG_MTD_PARTITIONS
  5517. +static struct mtd_partition tl_wr1043nd_partitions[] = {
  5518. + {
  5519. + .name = "u-boot",
  5520. + .offset = 0,
  5521. + .size = 0x020000,
  5522. + .mask_flags = MTD_WRITEABLE,
  5523. + } , {
  5524. + .name = "kernel",
  5525. + .offset = 0x020000,
  5526. + .size = 0x140000,
  5527. + } , {
  5528. + .name = "rootfs",
  5529. + .offset = 0x160000,
  5530. + .size = 0x690000,
  5531. + } , {
  5532. + .name = "art",
  5533. + .offset = 0x7f0000,
  5534. + .size = 0x010000,
  5535. + .mask_flags = MTD_WRITEABLE,
  5536. + } , {
  5537. + .name = "firmware",
  5538. + .offset = 0x020000,
  5539. + .size = 0x7d0000,
  5540. + }
  5541. +};
  5542. +#endif /* CONFIG_MTD_PARTITIONS */
  5543. +
  5544. +static struct flash_platform_data tl_wr1043nd_flash_data = {
  5545. +#ifdef CONFIG_MTD_PARTITIONS
  5546. + .parts = tl_wr1043nd_partitions,
  5547. + .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions),
  5548. +#endif
  5549. +};
  5550. +
  5551. +static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
  5552. + {
  5553. + .name = "tl-wr1043nd:green:usb",
  5554. + .gpio = TL_WR1043ND_GPIO_LED_USB,
  5555. + .active_low = 1,
  5556. + }, {
  5557. + .name = "tl-wr1043nd:green:system",
  5558. + .gpio = TL_WR1043ND_GPIO_LED_SYSTEM,
  5559. + .active_low = 1,
  5560. + }, {
  5561. + .name = "tl-wr1043nd:green:qss",
  5562. + .gpio = TL_WR1043ND_GPIO_LED_QSS,
  5563. + .active_low = 0,
  5564. + }, {
  5565. + .name = "tl-wr1043nd:green:wlan",
  5566. + .gpio = TL_WR1043ND_GPIO_LED_WLAN,
  5567. + .active_low = 1,
  5568. + }
  5569. +};
  5570. +
  5571. +static struct gpio_button tl_wr1043nd_gpio_buttons[] __initdata = {
  5572. + {
  5573. + .desc = "reset",
  5574. + .type = EV_KEY,
  5575. + .code = KEY_RESTART,
  5576. + .threshold = 3,
  5577. + .gpio = TL_WR1043ND_GPIO_BTN_RESET,
  5578. + .active_low = 1,
  5579. + }, {
  5580. + .desc = "qss",
  5581. + .type = EV_KEY,
  5582. + .code = KEY_WPS_BUTTON,
  5583. + .threshold = 3,
  5584. + .gpio = TL_WR1043ND_GPIO_BTN_QSS,
  5585. + .active_low = 1,
  5586. + }
  5587. +};
  5588. +
  5589. +static struct rtl8366rb_platform_data tl_wr1043nd_rtl8366rb_data = {
  5590. + .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA,
  5591. + .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK,
  5592. +};
  5593. +
  5594. +static struct platform_device tl_wr1043nd_rtl8366rb_device = {
  5595. + .name = RTL8366RB_DRIVER_NAME,
  5596. + .id = -1,
  5597. + .dev = {
  5598. + .platform_data = &tl_wr1043nd_rtl8366rb_data,
  5599. + }
  5600. +};
  5601. +
  5602. +static void __init tl_wr1043nd_setup(void)
  5603. +{
  5604. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5605. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  5606. +
  5607. + ar71xx_set_mac_base(mac);
  5608. +
  5609. + ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev;
  5610. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  5611. + ar71xx_eth0_data.speed = SPEED_1000;
  5612. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5613. + ar71xx_eth0_pll_data.pll_1000 = 0x1a000000;
  5614. +
  5615. + ar71xx_add_device_eth(0);
  5616. +
  5617. + ar71xx_add_device_usb();
  5618. +
  5619. + ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data);
  5620. +
  5621. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio),
  5622. + tl_wr1043nd_leds_gpio);
  5623. +
  5624. + platform_device_register(&tl_wr1043nd_rtl8366rb_device);
  5625. +
  5626. + ar71xx_add_device_gpio_buttons(-1, TL_WR1043ND_BUTTONS_POLL_INTERVAL,
  5627. + ARRAY_SIZE(tl_wr1043nd_gpio_buttons),
  5628. + tl_wr1043nd_gpio_buttons);
  5629. +
  5630. + ar913x_add_device_wmac(eeprom, mac);
  5631. +}
  5632. +
  5633. +MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND",
  5634. + tl_wr1043nd_setup);
  5635. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.37/arch/mips/ar71xx/mach-tl-wr741nd.c
  5636. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100
  5637. +++ linux-2.6.37/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-01-11 20:25:48.000000000 +0100
  5638. @@ -0,0 +1,115 @@
  5639. +/*
  5640. + * TP-LINK TL-WR741ND board support
  5641. + *
  5642. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5643. + *
  5644. + * This program is free software; you can redistribute it and/or modify it
  5645. + * under the terms of the GNU General Public License version 2 as published
  5646. + * by the Free Software Foundation.
  5647. + */
  5648. +
  5649. +#include <linux/mtd/mtd.h>
  5650. +#include <linux/mtd/partitions.h>
  5651. +
  5652. +#include <asm/mach-ar71xx/ar71xx.h>
  5653. +
  5654. +#include "machtype.h"
  5655. +#include "devices.h"
  5656. +#include "dev-m25p80.h"
  5657. +#include "dev-ap91-eth.h"
  5658. +#include "dev-ap91-pci.h"
  5659. +#include "dev-gpio-buttons.h"
  5660. +#include "dev-leds-gpio.h"
  5661. +
  5662. +#define TL_WR741ND_GPIO_LED_QSS 0
  5663. +#define TL_WR741ND_GPIO_LED_SYSTEM 1
  5664. +
  5665. +#define TL_WR741ND_GPIO_BTN_RESET 11
  5666. +#define TL_WR741ND_GPIO_BTN_QSS 12
  5667. +
  5668. +#define TL_WR741ND_BUTTONS_POLL_INTERVAL 20
  5669. +
  5670. +#ifdef CONFIG_MTD_PARTITIONS
  5671. +static struct mtd_partition tl_wr741nd_partitions[] = {
  5672. + {
  5673. + .name = "u-boot",
  5674. + .offset = 0,
  5675. + .size = 0x020000,
  5676. + .mask_flags = MTD_WRITEABLE,
  5677. + } , {
  5678. + .name = "kernel",
  5679. + .offset = 0x020000,
  5680. + .size = 0x140000,
  5681. + } , {
  5682. + .name = "rootfs",
  5683. + .offset = 0x160000,
  5684. + .size = 0x290000,
  5685. + } , {
  5686. + .name = "art",
  5687. + .offset = 0x3f0000,
  5688. + .size = 0x010000,
  5689. + .mask_flags = MTD_WRITEABLE,
  5690. + } , {
  5691. + .name = "firmware",
  5692. + .offset = 0x020000,
  5693. + .size = 0x3d0000,
  5694. + }
  5695. +};
  5696. +#endif /* CONFIG_MTD_PARTITIONS */
  5697. +
  5698. +static struct flash_platform_data tl_wr741nd_flash_data = {
  5699. +#ifdef CONFIG_MTD_PARTITIONS
  5700. + .parts = tl_wr741nd_partitions,
  5701. + .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions),
  5702. +#endif
  5703. +};
  5704. +
  5705. +static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = {
  5706. + {
  5707. + .name = "tl-wr741nd:green:system",
  5708. + .gpio = TL_WR741ND_GPIO_LED_SYSTEM,
  5709. + .active_low = 1,
  5710. + }, {
  5711. + .name = "tl-wr741nd:green:qss",
  5712. + .gpio = TL_WR741ND_GPIO_LED_QSS,
  5713. + .active_low = 1,
  5714. + }
  5715. +};
  5716. +
  5717. +static struct gpio_button tl_wr741nd_gpio_buttons[] __initdata = {
  5718. + {
  5719. + .desc = "reset",
  5720. + .type = EV_KEY,
  5721. + .code = KEY_RESTART,
  5722. + .threshold = 3,
  5723. + .gpio = TL_WR741ND_GPIO_BTN_RESET,
  5724. + .active_low = 1,
  5725. + }, {
  5726. + .desc = "qss",
  5727. + .type = EV_KEY,
  5728. + .code = KEY_WPS_BUTTON,
  5729. + .threshold = 3,
  5730. + .gpio = TL_WR741ND_GPIO_BTN_QSS,
  5731. + .active_low = 1,
  5732. + }
  5733. +};
  5734. +
  5735. +static void __init tl_wr741nd_setup(void)
  5736. +{
  5737. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5738. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  5739. +
  5740. + ar71xx_add_device_m25p80(&tl_wr741nd_flash_data);
  5741. +
  5742. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio),
  5743. + tl_wr741nd_leds_gpio);
  5744. +
  5745. + ar71xx_add_device_gpio_buttons(-1, TL_WR741ND_BUTTONS_POLL_INTERVAL,
  5746. + ARRAY_SIZE(tl_wr741nd_gpio_buttons),
  5747. + tl_wr741nd_gpio_buttons);
  5748. +
  5749. + ap91_eth_init(mac, NULL);
  5750. + ap91_pci_init(ee, mac);
  5751. +}
  5752. +MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND",
  5753. + tl_wr741nd_setup);
  5754. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.37/arch/mips/ar71xx/mach-tl-wr841n.c
  5755. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100
  5756. +++ linux-2.6.37/arch/mips/ar71xx/mach-tl-wr841n.c 2011-01-11 20:25:48.000000000 +0100
  5757. @@ -0,0 +1,143 @@
  5758. +/*
  5759. + * TP-LINK TL-WR841N board support
  5760. + *
  5761. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  5762. + *
  5763. + * This program is free software; you can redistribute it and/or modify it
  5764. + * under the terms of the GNU General Public License version 2 as published
  5765. + * by the Free Software Foundation.
  5766. + */
  5767. +
  5768. +#include <linux/mtd/mtd.h>
  5769. +#include <linux/mtd/partitions.h>
  5770. +
  5771. +#include <asm/mach-ar71xx/ar71xx.h>
  5772. +
  5773. +#include "machtype.h"
  5774. +#include "devices.h"
  5775. +#include "dev-dsa.h"
  5776. +#include "dev-m25p80.h"
  5777. +#include "dev-gpio-buttons.h"
  5778. +#include "dev-pb42-pci.h"
  5779. +#include "dev-leds-gpio.h"
  5780. +
  5781. +#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2
  5782. +#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4
  5783. +#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5
  5784. +
  5785. +#define TL_WR841ND_V1_GPIO_BTN_RESET 3
  5786. +#define TL_WR841ND_V1_GPIO_BTN_QSS 7
  5787. +
  5788. +#define TL_WR841ND_V1_BUTTONS_POLL_INTERVAL 20
  5789. +
  5790. +#ifdef CONFIG_MTD_PARTITIONS
  5791. +static struct mtd_partition tl_wr841n_v1_partitions[] = {
  5792. + {
  5793. + .name = "redboot",
  5794. + .offset = 0,
  5795. + .size = 0x020000,
  5796. + .mask_flags = MTD_WRITEABLE,
  5797. + } , {
  5798. + .name = "kernel",
  5799. + .offset = 0x020000,
  5800. + .size = 0x140000,
  5801. + } , {
  5802. + .name = "rootfs",
  5803. + .offset = 0x160000,
  5804. + .size = 0x280000,
  5805. + } , {
  5806. + .name = "config",
  5807. + .offset = 0x3e0000,
  5808. + .size = 0x020000,
  5809. + .mask_flags = MTD_WRITEABLE,
  5810. + } , {
  5811. + .name = "firmware",
  5812. + .offset = 0x020000,
  5813. + .size = 0x3c0000,
  5814. + }
  5815. +};
  5816. +#endif /* CONFIG_MTD_PARTITIONS */
  5817. +
  5818. +static struct flash_platform_data tl_wr841n_v1_flash_data = {
  5819. +#ifdef CONFIG_MTD_PARTITIONS
  5820. + .parts = tl_wr841n_v1_partitions,
  5821. + .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions),
  5822. +#endif
  5823. +};
  5824. +
  5825. +static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = {
  5826. + {
  5827. + .name = "tl-wr841n:green:system",
  5828. + .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM,
  5829. + .active_low = 1,
  5830. + }, {
  5831. + .name = "tl-wr841n:red:qss",
  5832. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED,
  5833. + }, {
  5834. + .name = "tl-wr841n:green:qss",
  5835. + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN,
  5836. + }
  5837. +};
  5838. +
  5839. +static struct gpio_button tl_wr841n_v1_gpio_buttons[] __initdata = {
  5840. + {
  5841. + .desc = "reset",
  5842. + .type = EV_KEY,
  5843. + .code = KEY_RESTART,
  5844. + .threshold = 3,
  5845. + .gpio = TL_WR841ND_V1_GPIO_BTN_RESET,
  5846. + .active_low = 1,
  5847. + }, {
  5848. + .desc = "qss",
  5849. + .type = EV_KEY,
  5850. + .code = KEY_WPS_BUTTON,
  5851. + .threshold = 3,
  5852. + .gpio = TL_WR841ND_V1_GPIO_BTN_QSS,
  5853. + .active_low = 1,
  5854. + }
  5855. +};
  5856. +
  5857. +static struct dsa_chip_data tl_wr841n_v1_dsa_chip = {
  5858. + .port_names[0] = "wan",
  5859. + .port_names[1] = "lan1",
  5860. + .port_names[2] = "lan2",
  5861. + .port_names[3] = "lan3",
  5862. + .port_names[4] = "lan4",
  5863. + .port_names[5] = "cpu",
  5864. +};
  5865. +
  5866. +static struct dsa_platform_data tl_wr841n_v1_dsa_data = {
  5867. + .nr_chips = 1,
  5868. + .chip = &tl_wr841n_v1_dsa_chip,
  5869. +};
  5870. +
  5871. +static void __init tl_wr841n_v1_setup(void)
  5872. +{
  5873. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  5874. +
  5875. + ar71xx_set_mac_base(mac);
  5876. +
  5877. + ar71xx_add_device_mdio(0x0);
  5878. +
  5879. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  5880. + ar71xx_eth0_data.speed = SPEED_100;
  5881. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  5882. +
  5883. + ar71xx_add_device_eth(0);
  5884. +
  5885. + ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data);
  5886. +
  5887. + ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data);
  5888. +
  5889. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio),
  5890. + tl_wr841n_v1_leds_gpio);
  5891. +
  5892. + ar71xx_add_device_gpio_buttons(-1, TL_WR841ND_V1_BUTTONS_POLL_INTERVAL,
  5893. + ARRAY_SIZE(tl_wr841n_v1_gpio_buttons),
  5894. + tl_wr841n_v1_gpio_buttons);
  5895. +
  5896. + pb42_pci_init();
  5897. +}
  5898. +
  5899. +MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1",
  5900. + tl_wr841n_v1_setup);
  5901. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.37/arch/mips/ar71xx/mach-tl-wr941nd.c
  5902. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100
  5903. +++ linux-2.6.37/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-01-11 20:25:48.000000000 +0100
  5904. @@ -0,0 +1,142 @@
  5905. +/*
  5906. + * TP-LINK TL-WR941ND board support
  5907. + *
  5908. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  5909. + *
  5910. + * This program is free software; you can redistribute it and/or modify it
  5911. + * under the terms of the GNU General Public License version 2 as published
  5912. + * by the Free Software Foundation.
  5913. + */
  5914. +
  5915. +#include <linux/mtd/mtd.h>
  5916. +#include <linux/mtd/partitions.h>
  5917. +
  5918. +#include <asm/mach-ar71xx/ar71xx.h>
  5919. +
  5920. +#include "machtype.h"
  5921. +#include "devices.h"
  5922. +#include "dev-dsa.h"
  5923. +#include "dev-m25p80.h"
  5924. +#include "dev-ar913x-wmac.h"
  5925. +#include "dev-gpio-buttons.h"
  5926. +#include "dev-leds-gpio.h"
  5927. +
  5928. +#define TL_WR941ND_GPIO_LED_SYSTEM 2
  5929. +#define TL_WR941ND_GPIO_LED_QSS_RED 4
  5930. +#define TL_WR941ND_GPIO_LED_QSS_GREEN 5
  5931. +
  5932. +#define TL_WR941ND_GPIO_BTN_RESET 3
  5933. +#define TL_WR941ND_GPIO_BTN_QSS 7
  5934. +
  5935. +#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20
  5936. +
  5937. +#ifdef CONFIG_MTD_PARTITIONS
  5938. +static struct mtd_partition tl_wr941nd_partitions[] = {
  5939. + {
  5940. + .name = "u-boot",
  5941. + .offset = 0,
  5942. + .size = 0x020000,
  5943. + .mask_flags = MTD_WRITEABLE,
  5944. + } , {
  5945. + .name = "kernel",
  5946. + .offset = 0x020000,
  5947. + .size = 0x140000,
  5948. + } , {
  5949. + .name = "rootfs",
  5950. + .offset = 0x160000,
  5951. + .size = 0x290000,
  5952. + } , {
  5953. + .name = "art",
  5954. + .offset = 0x3f0000,
  5955. + .size = 0x010000,
  5956. + .mask_flags = MTD_WRITEABLE,
  5957. + } , {
  5958. + .name = "firmware",
  5959. + .offset = 0x020000,
  5960. + .size = 0x3d0000,
  5961. + }
  5962. +};
  5963. +#endif /* CONFIG_MTD_PARTITIONS */
  5964. +
  5965. +static struct flash_platform_data tl_wr941nd_flash_data = {
  5966. +#ifdef CONFIG_MTD_PARTITIONS
  5967. + .parts = tl_wr941nd_partitions,
  5968. + .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions),
  5969. +#endif
  5970. +};
  5971. +
  5972. +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = {
  5973. + {
  5974. + .name = "tl-wr941nd:green:system",
  5975. + .gpio = TL_WR941ND_GPIO_LED_SYSTEM,
  5976. + .active_low = 1,
  5977. + }, {
  5978. + .name = "tl-wr941nd:red:qss",
  5979. + .gpio = TL_WR941ND_GPIO_LED_QSS_RED,
  5980. + }, {
  5981. + .name = "tl-wr941nd:green:qss",
  5982. + .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN,
  5983. + }
  5984. +};
  5985. +
  5986. +static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = {
  5987. + {
  5988. + .desc = "reset",
  5989. + .type = EV_KEY,
  5990. + .code = KEY_RESTART,
  5991. + .threshold = 3,
  5992. + .gpio = TL_WR941ND_GPIO_BTN_RESET,
  5993. + .active_low = 1,
  5994. + }, {
  5995. + .desc = "qss",
  5996. + .type = EV_KEY,
  5997. + .code = KEY_WPS_BUTTON,
  5998. + .threshold = 3,
  5999. + .gpio = TL_WR941ND_GPIO_BTN_QSS,
  6000. + .active_low = 1,
  6001. + }
  6002. +};
  6003. +
  6004. +static struct dsa_chip_data tl_wr941nd_dsa_chip = {
  6005. + .port_names[0] = "wan",
  6006. + .port_names[1] = "lan1",
  6007. + .port_names[2] = "lan2",
  6008. + .port_names[3] = "lan3",
  6009. + .port_names[4] = "lan4",
  6010. + .port_names[5] = "cpu",
  6011. +};
  6012. +
  6013. +static struct dsa_platform_data tl_wr941nd_dsa_data = {
  6014. + .nr_chips = 1,
  6015. + .chip = &tl_wr941nd_dsa_chip,
  6016. +};
  6017. +
  6018. +static void __init tl_wr941nd_setup(void)
  6019. +{
  6020. + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
  6021. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6022. +
  6023. + ar71xx_set_mac_base(mac);
  6024. +
  6025. + ar71xx_add_device_mdio(0x0);
  6026. +
  6027. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6028. + ar71xx_eth0_data.speed = SPEED_100;
  6029. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6030. +
  6031. + ar71xx_add_device_eth(0);
  6032. + ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data);
  6033. +
  6034. + ar71xx_add_device_m25p80(&tl_wr941nd_flash_data);
  6035. +
  6036. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio),
  6037. + tl_wr941nd_leds_gpio);
  6038. +
  6039. + ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL,
  6040. + ARRAY_SIZE(tl_wr941nd_gpio_buttons),
  6041. + tl_wr941nd_gpio_buttons);
  6042. + ar913x_add_device_wmac(eeprom, mac);
  6043. +}
  6044. +
  6045. +MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND",
  6046. + tl_wr941nd_setup);
  6047. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.37/arch/mips/ar71xx/mach-ubnt.c
  6048. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100
  6049. +++ linux-2.6.37/arch/mips/ar71xx/mach-ubnt.c 2011-01-11 20:25:48.000000000 +0100
  6050. @@ -0,0 +1,281 @@
  6051. +/*
  6052. + * Ubiquiti RouterStation support
  6053. + *
  6054. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6055. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6056. + * Copyright (C) 2008 Ubiquiti <support@ubnt.com>
  6057. + *
  6058. + * This program is free software; you can redistribute it and/or modify it
  6059. + * under the terms of the GNU General Public License version 2 as published
  6060. + * by the Free Software Foundation.
  6061. + */
  6062. +
  6063. +#include <asm/mach-ar71xx/ar71xx.h>
  6064. +
  6065. +#include "machtype.h"
  6066. +#include "devices.h"
  6067. +#include "dev-m25p80.h"
  6068. +#include "dev-ap91-pci.h"
  6069. +#include "dev-gpio-buttons.h"
  6070. +#include "dev-pb42-pci.h"
  6071. +#include "dev-leds-gpio.h"
  6072. +#include "dev-usb.h"
  6073. +
  6074. +#define UBNT_RS_GPIO_LED_RF 2
  6075. +#define UBNT_RS_GPIO_SW4 8
  6076. +
  6077. +#define UBNT_LS_SR71_GPIO_LED_D25 0
  6078. +#define UBNT_LS_SR71_GPIO_LED_D26 1
  6079. +#define UBNT_LS_SR71_GPIO_LED_D24 2
  6080. +#define UBNT_LS_SR71_GPIO_LED_D23 4
  6081. +#define UBNT_LS_SR71_GPIO_LED_D22 5
  6082. +#define UBNT_LS_SR71_GPIO_LED_D27 6
  6083. +#define UBNT_LS_SR71_GPIO_LED_D28 7
  6084. +
  6085. +#define UBNT_M_GPIO_LED_L1 0
  6086. +#define UBNT_M_GPIO_LED_L2 1
  6087. +#define UBNT_M_GPIO_LED_L3 11
  6088. +#define UBNT_M_GPIO_LED_L4 7
  6089. +#define UBNT_M_GPIO_BTN_RESET 12
  6090. +
  6091. +#define UBNT_BUTTONS_POLL_INTERVAL 20
  6092. +
  6093. +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = {
  6094. + {
  6095. + .name = "ubnt:green:rf",
  6096. + .gpio = UBNT_RS_GPIO_LED_RF,
  6097. + .active_low = 0,
  6098. + }
  6099. +};
  6100. +
  6101. +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = {
  6102. + {
  6103. + .name = "ubnt:green:d22",
  6104. + .gpio = UBNT_LS_SR71_GPIO_LED_D22,
  6105. + .active_low = 0,
  6106. + }, {
  6107. + .name = "ubnt:green:d23",
  6108. + .gpio = UBNT_LS_SR71_GPIO_LED_D23,
  6109. + .active_low = 0,
  6110. + }, {
  6111. + .name = "ubnt:green:d24",
  6112. + .gpio = UBNT_LS_SR71_GPIO_LED_D24,
  6113. + .active_low = 0,
  6114. + }, {
  6115. + .name = "ubnt:red:d25",
  6116. + .gpio = UBNT_LS_SR71_GPIO_LED_D25,
  6117. + .active_low = 0,
  6118. + }, {
  6119. + .name = "ubnt:red:d26",
  6120. + .gpio = UBNT_LS_SR71_GPIO_LED_D26,
  6121. + .active_low = 0,
  6122. + }, {
  6123. + .name = "ubnt:green:d27",
  6124. + .gpio = UBNT_LS_SR71_GPIO_LED_D27,
  6125. + .active_low = 0,
  6126. + }, {
  6127. + .name = "ubnt:green:d28",
  6128. + .gpio = UBNT_LS_SR71_GPIO_LED_D28,
  6129. + .active_low = 0,
  6130. + }
  6131. +};
  6132. +
  6133. +static struct gpio_led ubnt_m_leds_gpio[] __initdata = {
  6134. + {
  6135. + .name = "ubnt:red:link1",
  6136. + .gpio = UBNT_M_GPIO_LED_L1,
  6137. + .active_low = 0,
  6138. + }, {
  6139. + .name = "ubnt:orange:link2",
  6140. + .gpio = UBNT_M_GPIO_LED_L2,
  6141. + .active_low = 0,
  6142. + }, {
  6143. + .name = "ubnt:green:link3",
  6144. + .gpio = UBNT_M_GPIO_LED_L3,
  6145. + .active_low = 0,
  6146. + }, {
  6147. + .name = "ubnt:green:link4",
  6148. + .gpio = UBNT_M_GPIO_LED_L4,
  6149. + .active_low = 0,
  6150. + }
  6151. +};
  6152. +
  6153. +static struct gpio_button ubnt_gpio_buttons[] __initdata = {
  6154. + {
  6155. + .desc = "sw4",
  6156. + .type = EV_KEY,
  6157. + .code = KEY_RESTART,
  6158. + .threshold = 3,
  6159. + .gpio = UBNT_RS_GPIO_SW4,
  6160. + .active_low = 1,
  6161. + }
  6162. +};
  6163. +
  6164. +static struct gpio_button ubnt_m_gpio_buttons[] __initdata = {
  6165. + {
  6166. + .desc = "reset",
  6167. + .type = EV_KEY,
  6168. + .code = KEY_RESTART,
  6169. + .threshold = 3,
  6170. + .gpio = UBNT_M_GPIO_BTN_RESET,
  6171. + .active_low = 1,
  6172. + }
  6173. +};
  6174. +
  6175. +static void __init ubnt_generic_setup(void)
  6176. +{
  6177. + ar71xx_add_device_m25p80(NULL);
  6178. +
  6179. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6180. + ARRAY_SIZE(ubnt_gpio_buttons),
  6181. + ubnt_gpio_buttons);
  6182. +
  6183. + pb42_pci_init();
  6184. +}
  6185. +
  6186. +#define UBNT_RS_WAN_PHYMASK (1 << 20)
  6187. +#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19))
  6188. +
  6189. +static void __init ubnt_rs_setup(void)
  6190. +{
  6191. + ubnt_generic_setup();
  6192. +
  6193. + ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK));
  6194. +
  6195. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6196. + ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK;
  6197. +
  6198. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6199. + ar71xx_eth1_data.speed = SPEED_100;
  6200. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6201. +
  6202. + ar71xx_add_device_eth(0);
  6203. + ar71xx_add_device_eth(1);
  6204. +
  6205. + ar71xx_add_device_usb();
  6206. +
  6207. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6208. + ubnt_rs_leds_gpio);
  6209. +}
  6210. +
  6211. +MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation",
  6212. + ubnt_rs_setup);
  6213. +
  6214. +MIPS_MACHINE(AR71XX_MACH_UBNT_AR71XX, "Ubiquiti AR71xx-based board",
  6215. + "Ubiquiti RouterStation", ubnt_rs_setup);
  6216. +
  6217. +#define UBNT_RSPRO_WAN_PHYMASK (1 << 4)
  6218. +#define UBNT_RSPRO_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
  6219. +
  6220. +static void __init ubnt_rspro_setup(void)
  6221. +{
  6222. + ubnt_generic_setup();
  6223. +
  6224. + ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | UBNT_RSPRO_LAN_PHYMASK));
  6225. +
  6226. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6227. + ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK;
  6228. +
  6229. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6230. + ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK;
  6231. + ar71xx_eth1_data.speed = SPEED_1000;
  6232. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6233. +
  6234. + ar71xx_add_device_eth(0);
  6235. + ar71xx_add_device_eth(1);
  6236. +
  6237. + ar71xx_add_device_usb();
  6238. +
  6239. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio),
  6240. + ubnt_rs_leds_gpio);
  6241. +}
  6242. +
  6243. +MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro",
  6244. + ubnt_rspro_setup);
  6245. +
  6246. +static void __init ubnt_lsx_setup(void)
  6247. +{
  6248. + ubnt_generic_setup();
  6249. +}
  6250. +
  6251. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup);
  6252. +
  6253. +#define UBNT_LSSR71_PHY_MASK (1 << 1)
  6254. +
  6255. +static void __init ubnt_lssr71_setup(void)
  6256. +{
  6257. + ubnt_generic_setup();
  6258. +
  6259. + ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK);
  6260. +
  6261. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6262. + ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK;
  6263. +
  6264. + ar71xx_add_device_eth(0);
  6265. +
  6266. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio),
  6267. + ubnt_ls_sr71_leds_gpio);
  6268. +}
  6269. +
  6270. +MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71",
  6271. + ubnt_lssr71_setup);
  6272. +
  6273. +static void __init ubnt_m_setup(void)
  6274. +{
  6275. + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
  6276. + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
  6277. +
  6278. + ar71xx_set_mac_base(mac);
  6279. +
  6280. + ar71xx_add_device_m25p80(NULL);
  6281. +
  6282. + ar71xx_add_device_mdio(~0);
  6283. +
  6284. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6285. + ar71xx_eth0_data.speed = SPEED_100;
  6286. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6287. + ar71xx_eth0_data.fifo_cfg1 = 0x0010ffff;
  6288. + ar71xx_eth0_data.fifo_cfg2 = 0x015500aa;
  6289. + ar71xx_eth0_data.fifo_cfg3 = 0x01f00140;
  6290. +
  6291. + ar71xx_add_device_eth(0);
  6292. +
  6293. + ap91_pci_init(ee, NULL);
  6294. +
  6295. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio),
  6296. + ubnt_m_leds_gpio);
  6297. +
  6298. + ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL,
  6299. + ARRAY_SIZE(ubnt_m_gpio_buttons),
  6300. + ubnt_m_gpio_buttons);
  6301. +}
  6302. +
  6303. +static void __init ubnt_rocket_m_setup(void)
  6304. +{
  6305. + ubnt_m_setup();
  6306. + ar71xx_add_device_usb();
  6307. +}
  6308. +
  6309. +MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M",
  6310. + ubnt_m_setup);
  6311. +MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M",
  6312. + ubnt_rocket_m_setup);
  6313. +
  6314. +/* TODO detect the second ethernet port and use one
  6315. + init function for all Ubiquiti MIMO series products */
  6316. +static void __init ubnt_nano_m_setup(void)
  6317. +{
  6318. + ubnt_m_setup();
  6319. +
  6320. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6321. + ar71xx_eth1_data.speed = SPEED_1000;
  6322. + ar71xx_eth1_data.duplex = DUPLEX_FULL;
  6323. + ar71xx_eth1_data.fifo_cfg1 = 0x0010ffff;
  6324. + ar71xx_eth1_data.fifo_cfg2 = 0x015500aa;
  6325. + ar71xx_eth1_data.fifo_cfg3 = 0x01f00140;
  6326. +
  6327. + ar71xx_add_device_eth(1);
  6328. +}
  6329. +
  6330. +MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M",
  6331. + ubnt_nano_m_setup);
  6332. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.37/arch/mips/ar71xx/mach-wndr3700.c
  6333. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100
  6334. +++ linux-2.6.37/arch/mips/ar71xx/mach-wndr3700.c 2011-01-11 20:25:48.000000000 +0100
  6335. @@ -0,0 +1,209 @@
  6336. +/*
  6337. + * Netgear WNDR3700 board support
  6338. + *
  6339. + * Copyright (C) 2009 Marco Porsch
  6340. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6341. + *
  6342. + * This program is free software; you can redistribute it and/or modify it
  6343. + * under the terms of the GNU General Public License version 2 as published
  6344. + * by the Free Software Foundation.
  6345. + */
  6346. +
  6347. +#include <linux/platform_device.h>
  6348. +#include <linux/mtd/mtd.h>
  6349. +#include <linux/mtd/partitions.h>
  6350. +#include <linux/delay.h>
  6351. +#include <linux/rtl8366s.h>
  6352. +
  6353. +#include <asm/mach-ar71xx/ar71xx.h>
  6354. +
  6355. +#include "machtype.h"
  6356. +#include "devices.h"
  6357. +#include "dev-m25p80.h"
  6358. +#include "dev-ap94-pci.h"
  6359. +#include "dev-gpio-buttons.h"
  6360. +#include "dev-leds-gpio.h"
  6361. +#include "dev-usb.h"
  6362. +
  6363. +#define WNDR3700_GPIO_LED_WPS_ORANGE 0
  6364. +#define WNDR3700_GPIO_LED_POWER_ORANGE 1
  6365. +#define WNDR3700_GPIO_LED_POWER_GREEN 2
  6366. +#define WNDR3700_GPIO_LED_WPS_GREEN 4
  6367. +#define WNDR3700_GPIO_LED_WAN_GREEN 6
  6368. +
  6369. +#define WNDR3700_GPIO_BTN_WPS 3
  6370. +#define WNDR3700_GPIO_BTN_RESET 8
  6371. +#define WNDR3700_GPIO_BTN_WIFI 11
  6372. +
  6373. +#define WNDR3700_GPIO_RTL8366_SDA 5
  6374. +#define WNDR3700_GPIO_RTL8366_SCK 7
  6375. +
  6376. +#define WNDR3700_BUTTONS_POLL_INTERVAL 20
  6377. +
  6378. +#define WNDR3700_WMAC0_MAC_OFFSET 0
  6379. +#define WNDR3700_WMAC1_MAC_OFFSET 0xc
  6380. +#define WNDR3700_CALDATA0_OFFSET 0x1000
  6381. +#define WNDR3700_CALDATA1_OFFSET 0x5000
  6382. +
  6383. +#ifdef CONFIG_MTD_PARTITIONS
  6384. +static struct mtd_partition wndr3700_partitions[] = {
  6385. + {
  6386. + .name = "uboot",
  6387. + .offset = 0,
  6388. + .size = 0x050000,
  6389. + .mask_flags = MTD_WRITEABLE,
  6390. + } , {
  6391. + .name = "env",
  6392. + .offset = 0x050000,
  6393. + .size = 0x020000,
  6394. + .mask_flags = MTD_WRITEABLE,
  6395. + } , {
  6396. + .name = "rootfs",
  6397. + .offset = 0x070000,
  6398. + .size = 0x720000,
  6399. + } , {
  6400. + .name = "config",
  6401. + .offset = 0x790000,
  6402. + .size = 0x010000,
  6403. + .mask_flags = MTD_WRITEABLE,
  6404. + } , {
  6405. + .name = "config_bak",
  6406. + .offset = 0x7a0000,
  6407. + .size = 0x010000,
  6408. + .mask_flags = MTD_WRITEABLE,
  6409. + } , {
  6410. + .name = "pot",
  6411. + .offset = 0x7b0000,
  6412. + .size = 0x010000,
  6413. + .mask_flags = MTD_WRITEABLE,
  6414. + } , {
  6415. + .name = "traffic_meter",
  6416. + .offset = 0x7c0000,
  6417. + .size = 0x010000,
  6418. + .mask_flags = MTD_WRITEABLE,
  6419. + } , {
  6420. + .name = "language",
  6421. + .offset = 0x7d0000,
  6422. + .size = 0x020000,
  6423. + .mask_flags = MTD_WRITEABLE,
  6424. + } , {
  6425. + .name = "caldata",
  6426. + .offset = 0x7f0000,
  6427. + .size = 0x010000,
  6428. + .mask_flags = MTD_WRITEABLE,
  6429. + }
  6430. +};
  6431. +#endif /* CONFIG_MTD_PARTITIONS */
  6432. +
  6433. +static struct flash_platform_data wndr3700_flash_data = {
  6434. +#ifdef CONFIG_MTD_PARTITIONS
  6435. + .parts = wndr3700_partitions,
  6436. + .nr_parts = ARRAY_SIZE(wndr3700_partitions),
  6437. +#endif
  6438. +};
  6439. +
  6440. +static struct gpio_led wndr3700_leds_gpio[] __initdata = {
  6441. + {
  6442. + .name = "wndr3700:green:power",
  6443. + .gpio = WNDR3700_GPIO_LED_POWER_GREEN,
  6444. + .active_low = 1,
  6445. + }, {
  6446. + .name = "wndr3700:orange:power",
  6447. + .gpio = WNDR3700_GPIO_LED_POWER_ORANGE,
  6448. + .active_low = 1,
  6449. + }, {
  6450. + .name = "wndr3700:green:wps",
  6451. + .gpio = WNDR3700_GPIO_LED_WPS_GREEN,
  6452. + .active_low = 1,
  6453. + }, {
  6454. + .name = "wndr3700:orange:wps",
  6455. + .gpio = WNDR3700_GPIO_LED_WPS_ORANGE,
  6456. + .active_low = 1,
  6457. + }, {
  6458. + .name = "wndr3700:green:wan",
  6459. + .gpio = WNDR3700_GPIO_LED_WAN_GREEN,
  6460. + .active_low = 1,
  6461. + }
  6462. +};
  6463. +
  6464. +static struct gpio_button wndr3700_gpio_buttons[] __initdata = {
  6465. + {
  6466. + .desc = "reset",
  6467. + .type = EV_KEY,
  6468. + .code = KEY_RESTART,
  6469. + .threshold = 3,
  6470. + .gpio = WNDR3700_GPIO_BTN_RESET,
  6471. + .active_low = 1,
  6472. + }, {
  6473. + .desc = "wps",
  6474. + .type = EV_KEY,
  6475. + .code = KEY_WPS_BUTTON,
  6476. + .threshold = 3,
  6477. + .gpio = WNDR3700_GPIO_BTN_WPS,
  6478. + .active_low = 1,
  6479. + } , {
  6480. + .desc = "wifi",
  6481. + .type = EV_KEY,
  6482. + .code = BTN_2,
  6483. + .threshold = 3,
  6484. + .gpio = WNDR3700_GPIO_BTN_WIFI,
  6485. + .active_low = 1,
  6486. + }
  6487. +};
  6488. +
  6489. +static struct rtl8366s_platform_data wndr3700_rtl8366s_data = {
  6490. + .gpio_sda = WNDR3700_GPIO_RTL8366_SDA,
  6491. + .gpio_sck = WNDR3700_GPIO_RTL8366_SCK,
  6492. +};
  6493. +
  6494. +static struct platform_device wndr3700_rtl8366s_device = {
  6495. + .name = RTL8366S_DRIVER_NAME,
  6496. + .id = -1,
  6497. + .dev = {
  6498. + .platform_data = &wndr3700_rtl8366s_data,
  6499. + }
  6500. +};
  6501. +
  6502. +static void __init wndr3700_setup(void)
  6503. +{
  6504. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  6505. +
  6506. + ar71xx_set_mac_base(art);
  6507. +
  6508. + ar71xx_eth0_pll_data.pll_1000 = 0x11110000;
  6509. + ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6510. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6511. + ar71xx_eth0_data.speed = SPEED_1000;
  6512. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6513. +
  6514. + ar71xx_eth1_pll_data.pll_1000 = 0x11110000;
  6515. + ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev;
  6516. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  6517. + ar71xx_eth1_data.phy_mask = 0x10;
  6518. +
  6519. + ar71xx_add_device_eth(0);
  6520. + ar71xx_add_device_eth(1);
  6521. +
  6522. + ar71xx_add_device_usb();
  6523. +
  6524. + ar71xx_add_device_m25p80(&wndr3700_flash_data);
  6525. +
  6526. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio),
  6527. + wndr3700_leds_gpio);
  6528. +
  6529. + ar71xx_add_device_gpio_buttons(-1, WNDR3700_BUTTONS_POLL_INTERVAL,
  6530. + ARRAY_SIZE(wndr3700_gpio_buttons),
  6531. + wndr3700_gpio_buttons);
  6532. +
  6533. + platform_device_register(&wndr3700_rtl8366s_device);
  6534. + platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0);
  6535. +
  6536. + ap94_pci_enable_quirk_wndr3700();
  6537. + ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET,
  6538. + art + WNDR3700_WMAC0_MAC_OFFSET,
  6539. + art + WNDR3700_CALDATA1_OFFSET,
  6540. + art + WNDR3700_WMAC1_MAC_OFFSET);
  6541. +}
  6542. +
  6543. +MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700",
  6544. + wndr3700_setup);
  6545. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.37/arch/mips/ar71xx/mach-wnr2000.c
  6546. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100
  6547. +++ linux-2.6.37/arch/mips/ar71xx/mach-wnr2000.c 2011-01-11 20:25:48.000000000 +0100
  6548. @@ -0,0 +1,148 @@
  6549. +/*
  6550. + * NETGEAR WNR2000 board support
  6551. + *
  6552. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6553. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6554. + * Copyright (C) 2008-2009 Andy Boyett <agb@openwrt.org>
  6555. + *
  6556. + * This program is free software; you can redistribute it and/or modify it
  6557. + * under the terms of the GNU General Public License version 2 as published
  6558. + * by the Free Software Foundation.
  6559. + */
  6560. +
  6561. +#include <linux/mtd/mtd.h>
  6562. +#include <linux/mtd/partitions.h>
  6563. +
  6564. +#include <asm/mach-ar71xx/ar71xx.h>
  6565. +
  6566. +#include "machtype.h"
  6567. +#include "devices.h"
  6568. +#include "dev-m25p80.h"
  6569. +#include "dev-ar913x-wmac.h"
  6570. +#include "dev-gpio-buttons.h"
  6571. +#include "dev-leds-gpio.h"
  6572. +
  6573. +#define WNR2000_GPIO_LED_PWR_GREEN 14
  6574. +#define WNR2000_GPIO_LED_PWR_AMBER 7
  6575. +#define WNR2000_GPIO_LED_WPS 4
  6576. +#define WNR2000_GPIO_LED_WLAN 6
  6577. +#define WNR2000_GPIO_BTN_RESET 21
  6578. +#define WNR2000_GPIO_BTN_WPS 8
  6579. +
  6580. +#define WNR2000_BUTTONS_POLL_INTERVAL 20
  6581. +
  6582. +#ifdef CONFIG_MTD_PARTITIONS
  6583. +static struct mtd_partition wnr2000_partitions[] = {
  6584. + {
  6585. + .name = "u-boot",
  6586. + .offset = 0,
  6587. + .size = 0x040000,
  6588. + .mask_flags = MTD_WRITEABLE,
  6589. + } , {
  6590. + .name = "u-boot-env",
  6591. + .offset = 0x040000,
  6592. + .size = 0x010000,
  6593. + } , {
  6594. + .name = "rootfs",
  6595. + .offset = 0x050000,
  6596. + .size = 0x240000,
  6597. + } , {
  6598. + .name = "user-config",
  6599. + .offset = 0x290000,
  6600. + .size = 0x010000,
  6601. + } , {
  6602. + .name = "uImage",
  6603. + .offset = 0x2a0000,
  6604. + .size = 0x120000,
  6605. + } , {
  6606. + .name = "language_table",
  6607. + .offset = 0x3c0000,
  6608. + .size = 0x020000,
  6609. + } , {
  6610. + .name = "rootfs_checksum",
  6611. + .offset = 0x3e0000,
  6612. + .size = 0x010000,
  6613. + } , {
  6614. + .name = "art",
  6615. + .offset = 0x3f0000,
  6616. + .size = 0x010000,
  6617. + .mask_flags = MTD_WRITEABLE,
  6618. + }
  6619. +};
  6620. +#endif /* CONFIG_MTD_PARTITIONS */
  6621. +
  6622. +static struct flash_platform_data wnr2000_flash_data = {
  6623. +#ifdef CONFIG_MTD_PARTITIONS
  6624. + .parts = wnr2000_partitions,
  6625. + .nr_parts = ARRAY_SIZE(wnr2000_partitions),
  6626. +#endif
  6627. +};
  6628. +
  6629. +static struct gpio_led wnr2000_leds_gpio[] __initdata = {
  6630. + {
  6631. + .name = "wnr2000:green:power",
  6632. + .gpio = WNR2000_GPIO_LED_PWR_GREEN,
  6633. + .active_low = 1,
  6634. + }, {
  6635. + .name = "wnr2000:amber:power",
  6636. + .gpio = WNR2000_GPIO_LED_PWR_AMBER,
  6637. + .active_low = 1,
  6638. + }, {
  6639. + .name = "wnr2000:green:wps",
  6640. + .gpio = WNR2000_GPIO_LED_WPS,
  6641. + .active_low = 1,
  6642. + }, {
  6643. + .name = "wnr2000:blue:wlan",
  6644. + .gpio = WNR2000_GPIO_LED_WLAN,
  6645. + .active_low = 1,
  6646. + }
  6647. +};
  6648. +
  6649. +static struct gpio_button wnr2000_gpio_buttons[] __initdata = {
  6650. + {
  6651. + .desc = "reset",
  6652. + .type = EV_KEY,
  6653. + .code = KEY_RESTART,
  6654. + .threshold = 3,
  6655. + .gpio = WNR2000_GPIO_BTN_RESET,
  6656. + }, {
  6657. + .desc = "wps",
  6658. + .type = EV_KEY,
  6659. + .code = KEY_WPS_BUTTON,
  6660. + .threshold = 3,
  6661. + .gpio = WNR2000_GPIO_BTN_WPS,
  6662. + }
  6663. +};
  6664. +
  6665. +static void __init wnr2000_setup(void)
  6666. +{
  6667. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6668. +
  6669. + ar71xx_set_mac_base(eeprom);
  6670. + ar71xx_add_device_mdio(0x0);
  6671. +
  6672. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6673. + ar71xx_eth0_data.speed = SPEED_100;
  6674. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  6675. + ar71xx_eth0_data.has_ar8216 = 1;
  6676. +
  6677. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6678. + ar71xx_eth1_data.phy_mask = 0x10;
  6679. +
  6680. + ar71xx_add_device_eth(0);
  6681. + ar71xx_add_device_eth(1);
  6682. +
  6683. + ar71xx_add_device_m25p80(&wnr2000_flash_data);
  6684. +
  6685. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio),
  6686. + wnr2000_leds_gpio);
  6687. +
  6688. + ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL,
  6689. + ARRAY_SIZE(wnr2000_gpio_buttons),
  6690. + wnr2000_gpio_buttons);
  6691. +
  6692. +
  6693. + ar913x_add_device_wmac(eeprom, NULL);
  6694. +}
  6695. +
  6696. +MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup);
  6697. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.37/arch/mips/ar71xx/mach-wp543.c
  6698. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100
  6699. +++ linux-2.6.37/arch/mips/ar71xx/mach-wp543.c 2011-01-11 20:25:48.000000000 +0100
  6700. @@ -0,0 +1,99 @@
  6701. +/*
  6702. + * Compex WP543/WPJ543 board support
  6703. + *
  6704. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  6705. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  6706. + *
  6707. + * This program is free software; you can redistribute it and/or modify it
  6708. + * under the terms of the GNU General Public License version 2 as published
  6709. + * by the Free Software Foundation.
  6710. + */
  6711. +
  6712. +#include <linux/mtd/mtd.h>
  6713. +#include <linux/mtd/partitions.h>
  6714. +
  6715. +#include <asm/mach-ar71xx/ar71xx.h>
  6716. +
  6717. +#include "machtype.h"
  6718. +#include "devices.h"
  6719. +#include "dev-m25p80.h"
  6720. +#include "dev-pb42-pci.h"
  6721. +#include "dev-gpio-buttons.h"
  6722. +#include "dev-leds-gpio.h"
  6723. +#include "dev-usb.h"
  6724. +
  6725. +#define WP543_GPIO_SW6 2
  6726. +#define WP543_GPIO_LED_1 3
  6727. +#define WP543_GPIO_LED_2 4
  6728. +#define WP543_GPIO_LED_WLAN 5
  6729. +#define WP543_GPIO_LED_CONN 6
  6730. +#define WP543_GPIO_LED_DIAG 7
  6731. +#define WP543_GPIO_SW4 8
  6732. +
  6733. +#define WP543_BUTTONS_POLL_INTERVAL 20
  6734. +
  6735. +static struct gpio_led wp543_leds_gpio[] __initdata = {
  6736. + {
  6737. + .name = "wp543:green:led1",
  6738. + .gpio = WP543_GPIO_LED_1,
  6739. + .active_low = 1,
  6740. + }, {
  6741. + .name = "wp543:green:led2",
  6742. + .gpio = WP543_GPIO_LED_2,
  6743. + .active_low = 1,
  6744. + }, {
  6745. + .name = "wp543:green:wlan",
  6746. + .gpio = WP543_GPIO_LED_WLAN,
  6747. + .active_low = 1,
  6748. + }, {
  6749. + .name = "wp543:green:conn",
  6750. + .gpio = WP543_GPIO_LED_CONN,
  6751. + .active_low = 1,
  6752. + }, {
  6753. + .name = "wp543:green:diag",
  6754. + .gpio = WP543_GPIO_LED_DIAG,
  6755. + .active_low = 1,
  6756. + }
  6757. +};
  6758. +
  6759. +static struct gpio_button wp543_gpio_buttons[] __initdata = {
  6760. + {
  6761. + .desc = "sw6",
  6762. + .type = EV_KEY,
  6763. + .code = BTN_0,
  6764. + .threshold = 3,
  6765. + .gpio = WP543_GPIO_SW6,
  6766. + }, {
  6767. + .desc = "sw4",
  6768. + .type = EV_KEY,
  6769. + .code = BTN_1,
  6770. + .threshold = 3,
  6771. + .gpio = WP543_GPIO_SW4,
  6772. + }
  6773. +};
  6774. +
  6775. +static void __init wp543_setup(void)
  6776. +{
  6777. + ar71xx_add_device_m25p80(NULL);
  6778. +
  6779. + ar71xx_add_device_mdio(0xfffffff7);
  6780. +
  6781. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
  6782. + ar71xx_eth0_data.phy_mask = 0x08;
  6783. + ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC |
  6784. + RESET_MODULE_GE0_PHY;
  6785. + ar71xx_add_device_eth(0);
  6786. +
  6787. + ar71xx_add_device_usb();
  6788. +
  6789. + pb42_pci_init();
  6790. +
  6791. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio),
  6792. + wp543_leds_gpio);
  6793. +
  6794. + ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL,
  6795. + ARRAY_SIZE(wp543_gpio_buttons),
  6796. + wp543_gpio_buttons);
  6797. +}
  6798. +
  6799. +MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup);
  6800. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.37/arch/mips/ar71xx/mach-wrt160nl.c
  6801. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100
  6802. +++ linux-2.6.37/arch/mips/ar71xx/mach-wrt160nl.c 2011-01-11 20:25:48.000000000 +0100
  6803. @@ -0,0 +1,158 @@
  6804. +/*
  6805. + * Linksys WRT160NL board support
  6806. + *
  6807. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  6808. + *
  6809. + * This program is free software; you can redistribute it and/or modify it
  6810. + * under the terms of the GNU General Public License version 2 as published
  6811. + * by the Free Software Foundation.
  6812. + */
  6813. +
  6814. +#include <linux/mtd/mtd.h>
  6815. +#include <linux/mtd/partitions.h>
  6816. +
  6817. +#include <asm/mach-ar71xx/ar71xx.h>
  6818. +
  6819. +#include "machtype.h"
  6820. +#include "devices.h"
  6821. +#include "dev-m25p80.h"
  6822. +#include "dev-ar913x-wmac.h"
  6823. +#include "dev-gpio-buttons.h"
  6824. +#include "dev-leds-gpio.h"
  6825. +#include "dev-usb.h"
  6826. +#include "nvram.h"
  6827. +
  6828. +#define WRT160NL_GPIO_LED_POWER 14
  6829. +#define WRT160NL_GPIO_LED_WPS_AMBER 9
  6830. +#define WRT160NL_GPIO_LED_WPS_BLUE 8
  6831. +#define WRT160NL_GPIO_LED_WLAN 6
  6832. +
  6833. +#define WRT160NL_GPIO_BTN_WPS 7
  6834. +#define WRT160NL_GPIO_BTN_RESET 21
  6835. +
  6836. +#define WRT160NL_BUTTONS_POLL_INTERVAL 20
  6837. +
  6838. +#define WRT160NL_NVRAM_ADDR 0x1f7e0000
  6839. +#define WRT160NL_NVRAM_SIZE 0x10000
  6840. +
  6841. +#ifdef CONFIG_MTD_PARTITIONS
  6842. +static struct mtd_partition wrt160nl_partitions[] = {
  6843. + {
  6844. + .name = "u-boot",
  6845. + .offset = 0,
  6846. + .size = 0x040000,
  6847. + .mask_flags = MTD_WRITEABLE,
  6848. + } , {
  6849. + .name = "kernel",
  6850. + .offset = 0x040000,
  6851. + .size = 0x0e0000,
  6852. + } , {
  6853. + .name = "filesytem",
  6854. + .offset = 0x120000,
  6855. + .size = 0x6c0000,
  6856. + } , {
  6857. + .name = "nvram",
  6858. + .offset = 0x7e0000,
  6859. + .size = 0x010000,
  6860. + .mask_flags = MTD_WRITEABLE,
  6861. + } , {
  6862. + .name = "ART",
  6863. + .offset = 0x7f0000,
  6864. + .size = 0x010000,
  6865. + .mask_flags = MTD_WRITEABLE,
  6866. + } , {
  6867. + .name = "firmware",
  6868. + .offset = 0x040000,
  6869. + .size = 0x7a0000,
  6870. + }
  6871. +};
  6872. +#endif /* CONFIG_MTD_PARTITIONS */
  6873. +
  6874. +static struct flash_platform_data wrt160nl_flash_data = {
  6875. +#ifdef CONFIG_MTD_PARTITIONS
  6876. + .parts = wrt160nl_partitions,
  6877. + .nr_parts = ARRAY_SIZE(wrt160nl_partitions),
  6878. +#endif
  6879. +};
  6880. +
  6881. +static struct gpio_led wrt160nl_leds_gpio[] __initdata = {
  6882. + {
  6883. + .name = "wrt160nl:blue:power",
  6884. + .gpio = WRT160NL_GPIO_LED_POWER,
  6885. + .active_low = 1,
  6886. + .default_trigger = "default-on",
  6887. + }, {
  6888. + .name = "wrt160nl:amber:wps",
  6889. + .gpio = WRT160NL_GPIO_LED_WPS_AMBER,
  6890. + .active_low = 1,
  6891. + }, {
  6892. + .name = "wrt160nl:blue:wps",
  6893. + .gpio = WRT160NL_GPIO_LED_WPS_BLUE,
  6894. + .active_low = 1,
  6895. + }, {
  6896. + .name = "wrt160nl:blue:wlan",
  6897. + .gpio = WRT160NL_GPIO_LED_WLAN,
  6898. + .active_low = 1,
  6899. + }
  6900. +};
  6901. +
  6902. +static struct gpio_button wrt160nl_gpio_buttons[] __initdata = {
  6903. + {
  6904. + .desc = "reset",
  6905. + .type = EV_KEY,
  6906. + .code = KEY_RESTART,
  6907. + .threshold = 3,
  6908. + .gpio = WRT160NL_GPIO_BTN_RESET,
  6909. + .active_low = 1,
  6910. + }, {
  6911. + .desc = "wps",
  6912. + .type = EV_KEY,
  6913. + .code = KEY_WPS_BUTTON,
  6914. + .threshold = 3,
  6915. + .gpio = WRT160NL_GPIO_BTN_WPS,
  6916. + .active_low = 1,
  6917. + }
  6918. +};
  6919. +
  6920. +static void __init wrt160nl_setup(void)
  6921. +{
  6922. + const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR);
  6923. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  6924. + u8 mac[6];
  6925. +
  6926. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6927. + "lan_hwaddr=", mac) == 0)
  6928. + ar71xx_set_mac_base(mac);
  6929. +
  6930. + ar71xx_add_device_mdio(0x0);
  6931. +
  6932. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6933. + ar71xx_eth0_data.phy_mask = 0x01;
  6934. +
  6935. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  6936. + ar71xx_eth1_data.phy_mask = 0x10;
  6937. +
  6938. + ar71xx_add_device_eth(0);
  6939. + ar71xx_add_device_eth(1);
  6940. +
  6941. + ar71xx_add_device_m25p80(&wrt160nl_flash_data);
  6942. +
  6943. + ar71xx_add_device_usb();
  6944. +
  6945. + if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE,
  6946. + "wl0_hwaddr=", mac) == 0)
  6947. + ar913x_add_device_wmac(eeprom, mac);
  6948. + else
  6949. + ar913x_add_device_wmac(eeprom, NULL);
  6950. +
  6951. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio),
  6952. + wrt160nl_leds_gpio);
  6953. +
  6954. + ar71xx_add_device_gpio_buttons(-1, WRT160NL_BUTTONS_POLL_INTERVAL,
  6955. + ARRAY_SIZE(wrt160nl_gpio_buttons),
  6956. + wrt160nl_gpio_buttons);
  6957. +
  6958. +}
  6959. +
  6960. +MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL",
  6961. + wrt160nl_setup);
  6962. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.37/arch/mips/ar71xx/mach-wrt400n.c
  6963. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100
  6964. +++ linux-2.6.37/arch/mips/ar71xx/mach-wrt400n.c 2011-01-11 20:25:48.000000000 +0100
  6965. @@ -0,0 +1,168 @@
  6966. +/*
  6967. + * Linksys WRT400N board support
  6968. + *
  6969. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  6970. + * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
  6971. + *
  6972. + * This program is free software; you can redistribute it and/or modify it
  6973. + * under the terms of the GNU General Public License version 2 as published
  6974. + * by the Free Software Foundation.
  6975. + */
  6976. +
  6977. +#include <linux/mtd/mtd.h>
  6978. +#include <linux/mtd/partitions.h>
  6979. +
  6980. +#include <asm/mach-ar71xx/ar71xx.h>
  6981. +
  6982. +#include "machtype.h"
  6983. +#include "devices.h"
  6984. +#include "dev-ap94-pci.h"
  6985. +#include "dev-m25p80.h"
  6986. +#include "dev-gpio-buttons.h"
  6987. +#include "dev-leds-gpio.h"
  6988. +
  6989. +#define WRT400N_GPIO_LED_ORANGE 5
  6990. +#define WRT400N_GPIO_LED_GREEN 4
  6991. +#define WRT400N_GPIO_LED_POWER 1
  6992. +#define WRT400N_GPIO_LED_WLAN 0
  6993. +
  6994. +#define WRT400N_GPIO_BTN_RESET 8
  6995. +#define WRT400N_GPIO_BTN_WLSEC 3
  6996. +
  6997. +#define WRT400N_BUTTONS_POLL_INTERVAL 20
  6998. +
  6999. +#define WRT400N_MAC_ADDR_OFFSET 0x120c
  7000. +#define WRT400N_CALDATA0_OFFSET 0x1000
  7001. +#define WRT400N_CALDATA1_OFFSET 0x5000
  7002. +
  7003. +#ifdef CONFIG_MTD_PARTITIONS
  7004. +static struct mtd_partition wrt400n_partitions[] = {
  7005. + {
  7006. + .name = "uboot",
  7007. + .offset = 0,
  7008. + .size = 0x030000,
  7009. + .mask_flags = MTD_WRITEABLE,
  7010. + } , {
  7011. + .name = "env",
  7012. + .offset = 0x030000,
  7013. + .size = 0x010000,
  7014. + .mask_flags = MTD_WRITEABLE,
  7015. + } , {
  7016. + .name = "linux",
  7017. + .offset = 0x040000,
  7018. + .size = 0x140000,
  7019. + } , {
  7020. + .name = "rootfs",
  7021. + .offset = 0x180000,
  7022. + .size = 0x630000,
  7023. + } , {
  7024. + .name = "nvram",
  7025. + .offset = 0x7b0000,
  7026. + .size = 0x010000,
  7027. + .mask_flags = MTD_WRITEABLE,
  7028. + } , {
  7029. + .name = "factory",
  7030. + .offset = 0x7c0000,
  7031. + .size = 0x010000,
  7032. + .mask_flags = MTD_WRITEABLE,
  7033. + } , {
  7034. + .name = "language",
  7035. + .offset = 0x7d0000,
  7036. + .size = 0x020000,
  7037. + .mask_flags = MTD_WRITEABLE,
  7038. + } , {
  7039. + .name = "caldata",
  7040. + .offset = 0x7f0000,
  7041. + .size = 0x010000,
  7042. + .mask_flags = MTD_WRITEABLE,
  7043. + } , {
  7044. + .name = "firmware",
  7045. + .offset = 0x040000,
  7046. + .size = 0x770000,
  7047. + }
  7048. +};
  7049. +#endif /* CONFIG_MTD_PARTITIONS */
  7050. +
  7051. +static struct flash_platform_data wrt400n_flash_data = {
  7052. +#ifdef CONFIG_MTD_PARTITIONS
  7053. + .parts = wrt400n_partitions,
  7054. + .nr_parts = ARRAY_SIZE(wrt400n_partitions),
  7055. +#endif
  7056. +};
  7057. +
  7058. +static struct gpio_led wrt400n_leds_gpio[] __initdata = {
  7059. + {
  7060. + .name = "wrt400n:green:status",
  7061. + .gpio = WRT400N_GPIO_LED_GREEN,
  7062. + .active_low = 1,
  7063. + }, {
  7064. + .name = "wrt400n:amber:aoss",
  7065. + .gpio = WRT400N_GPIO_LED_ORANGE,
  7066. + .active_low = 1,
  7067. + }, {
  7068. + .name = "wrt400n:green:wlan",
  7069. + .gpio = WRT400N_GPIO_LED_WLAN,
  7070. + .active_low = 1,
  7071. + }, {
  7072. + .name = "wrt400n:green:power",
  7073. + .gpio = WRT400N_GPIO_LED_POWER,
  7074. + .active_low = 1,
  7075. + }
  7076. +};
  7077. +
  7078. +static struct gpio_button wrt400n_gpio_buttons[] __initdata = {
  7079. + {
  7080. + .desc = "reset",
  7081. + .type = EV_KEY,
  7082. + .code = KEY_RESTART,
  7083. + .threshold = 3,
  7084. + .gpio = WRT400N_GPIO_BTN_RESET,
  7085. + .active_low = 1,
  7086. + } , {
  7087. + .desc = "wlsec",
  7088. + .type = EV_KEY,
  7089. + .code = KEY_WPS_BUTTON,
  7090. + .threshold = 3,
  7091. + .gpio = WRT400N_GPIO_BTN_WLSEC,
  7092. + .active_low = 1,
  7093. + }
  7094. +};
  7095. +
  7096. +static void __init wrt400n_setup(void)
  7097. +{
  7098. + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
  7099. + u8 mac[6];
  7100. + int i;
  7101. +
  7102. + memcpy(mac, art + WRT400N_MAC_ADDR_OFFSET, 6);
  7103. + for (i = 5; i >= 3; i--)
  7104. + if (++mac[i] != 0x00) break;
  7105. +
  7106. + ar71xx_set_mac_base(mac);
  7107. +
  7108. + ar71xx_add_device_mdio(0x0);
  7109. +
  7110. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7111. + ar71xx_eth0_data.speed = SPEED_100;
  7112. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7113. +
  7114. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
  7115. + ar71xx_eth1_data.phy_mask = 0x10;
  7116. +
  7117. + ar71xx_add_device_eth(0);
  7118. + ar71xx_add_device_eth(1);
  7119. +
  7120. + ar71xx_add_device_m25p80(&wrt400n_flash_data);
  7121. +
  7122. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio),
  7123. + wrt400n_leds_gpio);
  7124. +
  7125. + ar71xx_add_device_gpio_buttons(-1, WRT400N_BUTTONS_POLL_INTERVAL,
  7126. + ARRAY_SIZE(wrt400n_gpio_buttons),
  7127. + wrt400n_gpio_buttons);
  7128. +
  7129. + ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL,
  7130. + art + WRT400N_CALDATA1_OFFSET, NULL);
  7131. +}
  7132. +
  7133. +MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup);
  7134. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.37/arch/mips/ar71xx/mach-wzr-hp-g300nh.c
  7135. --- linux-2.6.37.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100
  7136. +++ linux-2.6.37/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-01-11 20:25:48.000000000 +0100
  7137. @@ -0,0 +1,265 @@
  7138. +/*
  7139. + * Buffalo WZR-HP-G300NH board support
  7140. + *
  7141. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  7142. + *
  7143. + * This program is free software; you can redistribute it and/or modify it
  7144. + * under the terms of the GNU General Public License version 2 as published
  7145. + * by the Free Software Foundation.
  7146. + */
  7147. +
  7148. +#include <linux/platform_device.h>
  7149. +#include <linux/mtd/mtd.h>
  7150. +#include <linux/mtd/partitions.h>
  7151. +#include <linux/nxp_74hc153.h>
  7152. +#include <linux/rtl8366s.h>
  7153. +
  7154. +#include <asm/mips_machine.h>
  7155. +#include <asm/mach-ar71xx/ar71xx.h>
  7156. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  7157. +
  7158. +#include "machtype.h"
  7159. +#include "devices.h"
  7160. +#include "dev-ar913x-wmac.h"
  7161. +#include "dev-gpio-buttons.h"
  7162. +#include "dev-leds-gpio.h"
  7163. +#include "dev-usb.h"
  7164. +
  7165. +#define WZRHPG300NH_GPIO_LED_USB 0
  7166. +#define WZRHPG300NH_GPIO_LED_DIAG 1
  7167. +#define WZRHPG300NH_GPIO_LED_WIRELESS 6
  7168. +#define WZRHPG300NH_GPIO_LED_SECURITY 17
  7169. +#define WZRHPG300NH_GPIO_LED_ROUTER 18
  7170. +
  7171. +#define WZRHPG300NH_GPIO_RTL8366_SDA 19
  7172. +#define WZRHPG300NH_GPIO_RTL8366_SCK 20
  7173. +
  7174. +#define WZRHPG300NH_GPIO_74HC153_S0 9
  7175. +#define WZRHPG300NH_GPIO_74HC153_S1 11
  7176. +#define WZRHPG300NH_GPIO_74HC153_1Y 12
  7177. +#define WZRHPG300NH_GPIO_74HC153_2Y 14
  7178. +
  7179. +#define WZRHPG300NH_GPIO_EXP_BASE 32
  7180. +#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0)
  7181. +#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1)
  7182. +#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2)
  7183. +#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3)
  7184. +#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5)
  7185. +#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6)
  7186. +#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7)
  7187. +
  7188. +#define WZRHPG300NH_BUTTONS_POLL_INTERVAL 20
  7189. +
  7190. +#define WZRHPG300NH_MAC_OFFSET 0x20c
  7191. +
  7192. +#ifdef CONFIG_MTD_PARTITIONS
  7193. +static struct mtd_partition wzrhpg300nh_flash_partitions[] = {
  7194. + {
  7195. + .name = "u-boot",
  7196. + .offset = 0,
  7197. + .size = 0x0040000,
  7198. + .mask_flags = MTD_WRITEABLE,
  7199. + }, {
  7200. + .name = "u-boot-env",
  7201. + .offset = 0x0040000,
  7202. + .size = 0x0020000,
  7203. + .mask_flags = MTD_WRITEABLE,
  7204. + }, {
  7205. + .name = "kernel",
  7206. + .offset = 0x0060000,
  7207. + .size = 0x0100000,
  7208. + }, {
  7209. + .name = "rootfs",
  7210. + .offset = 0x0160000,
  7211. + .size = 0x1e60000,
  7212. + }, {
  7213. + .name = "user_property",
  7214. + .offset = 0x1fc0000,
  7215. + .size = 0x0020000,
  7216. + .mask_flags = MTD_WRITEABLE,
  7217. + }, {
  7218. + .name = "art",
  7219. + .offset = 0x1fe0000,
  7220. + .size = 0x0020000,
  7221. + .mask_flags = MTD_WRITEABLE,
  7222. + }, {
  7223. + .name = "firmware",
  7224. + .offset = 0x0060000,
  7225. + .size = 0x1f60000,
  7226. + }
  7227. +};
  7228. +#endif /* CONFIG_MTD_PARTITIONS */
  7229. +
  7230. +static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = {
  7231. + .width = 2,
  7232. +#ifdef CONFIG_MTD_PARTITIONS
  7233. + .parts = wzrhpg300nh_flash_partitions,
  7234. + .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions),
  7235. +#endif
  7236. +};
  7237. +
  7238. +#define WZRHPG300NH_FLASH_BASE 0x1e000000
  7239. +#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024)
  7240. +
  7241. +static struct resource wzrhpg300nh_flash_resources[] = {
  7242. + [0] = {
  7243. + .start = WZRHPG300NH_FLASH_BASE,
  7244. + .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1,
  7245. + .flags = IORESOURCE_MEM,
  7246. + },
  7247. +};
  7248. +
  7249. +static struct platform_device wzrhpg300nh_flash_device = {
  7250. + .name = "ar91xx-flash",
  7251. + .id = -1,
  7252. + .resource = wzrhpg300nh_flash_resources,
  7253. + .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources),
  7254. + .dev = {
  7255. + .platform_data = &wzrhpg300nh_flash_data,
  7256. + }
  7257. +};
  7258. +
  7259. +static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = {
  7260. + {
  7261. + .name = "wzr-hp-g300nh:orange:security",
  7262. + .gpio = WZRHPG300NH_GPIO_LED_SECURITY,
  7263. + .active_low = 1,
  7264. + }, {
  7265. + .name = "wzr-hp-g300nh:green:wireless",
  7266. + .gpio = WZRHPG300NH_GPIO_LED_WIRELESS,
  7267. + .active_low = 1,
  7268. + }, {
  7269. + .name = "wzr-hp-g300nh:green:router",
  7270. + .gpio = WZRHPG300NH_GPIO_LED_ROUTER,
  7271. + .active_low = 1,
  7272. + }, {
  7273. + .name = "wzr-hp-g300nh:red:diag",
  7274. + .gpio = WZRHPG300NH_GPIO_LED_DIAG,
  7275. + .active_low = 1,
  7276. + }, {
  7277. + .name = "wzr-hp-g300nh:blue:usb",
  7278. + .gpio = WZRHPG300NH_GPIO_LED_USB,
  7279. + .active_low = 1,
  7280. + }
  7281. +};
  7282. +
  7283. +static struct gpio_button wzrhpg300nh_gpio_buttons[] __initdata = {
  7284. + {
  7285. + .desc = "reset",
  7286. + .type = EV_KEY,
  7287. + .code = KEY_RESTART,
  7288. + .threshold = 3,
  7289. + .gpio = WZRHPG300NH_GPIO_BTN_RESET,
  7290. + .active_low = 1,
  7291. + }, {
  7292. + .desc = "aoss",
  7293. + .type = EV_KEY,
  7294. + .code = KEY_WPS_BUTTON,
  7295. + .threshold = 3,
  7296. + .gpio = WZRHPG300NH_GPIO_BTN_AOSS,
  7297. + .active_low = 1,
  7298. + }, {
  7299. + .desc = "usb",
  7300. + .type = EV_KEY,
  7301. + .code = BTN_2,
  7302. + .threshold = 3,
  7303. + .gpio = WZRHPG300NH_GPIO_BTN_USB,
  7304. + .active_low = 1,
  7305. + }, {
  7306. + .desc = "qos_on",
  7307. + .type = EV_KEY,
  7308. + .code = BTN_3,
  7309. + .threshold = 3,
  7310. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON,
  7311. + .active_low = 0,
  7312. + }, {
  7313. + .desc = "qos_off",
  7314. + .type = EV_KEY,
  7315. + .code = BTN_4,
  7316. + .threshold = 3,
  7317. + .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF,
  7318. + .active_low = 0,
  7319. + }, {
  7320. + .desc = "router_on",
  7321. + .type = EV_KEY,
  7322. + .code = BTN_5,
  7323. + .threshold = 3,
  7324. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON,
  7325. + .active_low = 0,
  7326. + }, {
  7327. + .desc = "router_auto",
  7328. + .type = EV_KEY,
  7329. + .code = BTN_6,
  7330. + .threshold = 3,
  7331. + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO,
  7332. + .active_low = 0,
  7333. + }
  7334. +};
  7335. +
  7336. +static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = {
  7337. + .gpio_base = WZRHPG300NH_GPIO_EXP_BASE,
  7338. + .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0,
  7339. + .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1,
  7340. + .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y,
  7341. + .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y,
  7342. +};
  7343. +
  7344. +static struct platform_device wzrhpg300nh_74hc153_device = {
  7345. + .name = NXP_74HC153_DRIVER_NAME,
  7346. + .id = -1,
  7347. + .dev = {
  7348. + .platform_data = &wzrhpg300nh_74hc153_data,
  7349. + }
  7350. +};
  7351. +
  7352. +static struct rtl8366s_platform_data wzrhpg300nh_rtl8366s_data = {
  7353. + .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA,
  7354. + .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK,
  7355. +};
  7356. +
  7357. +static struct platform_device wzrhpg300nh_rtl8366s_device = {
  7358. + .name = RTL8366S_DRIVER_NAME,
  7359. + .id = -1,
  7360. + .dev = {
  7361. + .platform_data = &wzrhpg300nh_rtl8366s_data,
  7362. + }
  7363. +};
  7364. +
  7365. +static void __init wzrhpg300nh_setup(void)
  7366. +{
  7367. + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000);
  7368. +
  7369. + ar71xx_set_mac_base(eeprom + WZRHPG300NH_MAC_OFFSET);
  7370. +
  7371. + ar71xx_eth0_pll_data.pll_1000 = 0x1e000100;
  7372. + ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7373. + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7374. + ar71xx_eth0_data.speed = SPEED_1000;
  7375. + ar71xx_eth0_data.duplex = DUPLEX_FULL;
  7376. +
  7377. + ar71xx_eth1_pll_data.pll_1000 = 0x1e000100;
  7378. + ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev;
  7379. + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
  7380. + ar71xx_eth1_data.phy_mask = 0x10;
  7381. +
  7382. + ar71xx_add_device_eth(0);
  7383. + ar71xx_add_device_eth(1);
  7384. +
  7385. + ar71xx_add_device_usb();
  7386. + ar913x_add_device_wmac(eeprom, NULL);
  7387. +
  7388. + platform_device_register(&wzrhpg300nh_74hc153_device);
  7389. + platform_device_register(&wzrhpg300nh_flash_device);
  7390. + platform_device_register(&wzrhpg300nh_rtl8366s_device);
  7391. +
  7392. + ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio),
  7393. + wzrhpg300nh_leds_gpio);
  7394. +
  7395. + ar71xx_add_device_gpio_buttons(-1, WZRHPG300NH_BUTTONS_POLL_INTERVAL,
  7396. + ARRAY_SIZE(wzrhpg300nh_gpio_buttons),
  7397. + wzrhpg300nh_gpio_buttons);
  7398. +
  7399. +}
  7400. +
  7401. +MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH",
  7402. + "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup);
  7403. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/machtype.h linux-2.6.37/arch/mips/ar71xx/machtype.h
  7404. --- linux-2.6.37.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100
  7405. +++ linux-2.6.37/arch/mips/ar71xx/machtype.h 2011-01-11 20:25:48.000000000 +0100
  7406. @@ -0,0 +1,60 @@
  7407. +/*
  7408. + * Atheros AR71xx machine type definitions
  7409. + *
  7410. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  7411. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7412. + *
  7413. + * This program is free software; you can redistribute it and/or modify it
  7414. + * under the terms of the GNU General Public License version 2 as published
  7415. + * by the Free Software Foundation.
  7416. + */
  7417. +
  7418. +#ifndef _AR71XX_MACHTYPE_H
  7419. +#define _AR71XX_MACHTYPE_H
  7420. +
  7421. +#include <asm/mips_machine.h>
  7422. +
  7423. +enum ar71xx_mach_type {
  7424. + AR71XX_MACH_GENERIC = 0,
  7425. + AR71XX_MACH_AP81, /* Atheros AP81 */
  7426. + AR71XX_MACH_AP83, /* Atheros AP83 */
  7427. + AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */
  7428. + AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */
  7429. + AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */
  7430. + AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */
  7431. + AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */
  7432. + AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */
  7433. + AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */
  7434. + AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */
  7435. + AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */
  7436. + AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */
  7437. + AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */
  7438. + AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */
  7439. + AR71XX_MACH_PB42, /* Atheros PB42 */
  7440. + AR71XX_MACH_PB44, /* Atheros PB44 */
  7441. + AR71XX_MACH_PB92, /* Atheros PB92 */
  7442. + AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */
  7443. + AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */
  7444. + AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */
  7445. + AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */
  7446. + AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */
  7447. + AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */
  7448. + AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */
  7449. + AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */
  7450. + AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */
  7451. + AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */
  7452. + AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */
  7453. + AR71XX_MACH_UBNT_AR71XX, /* Ubiquiti AR71xx-based board */
  7454. + AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
  7455. + AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */
  7456. + AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
  7457. + AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
  7458. + AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */
  7459. + AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */
  7460. + AR71XX_MACH_WP543, /* Compex WP543 */
  7461. + AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */
  7462. + AR71XX_MACH_WRT400N, /* Linksys WRT400N */
  7463. + AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */
  7464. +};
  7465. +
  7466. +#endif /* _AR71XX_MACHTYPE_H */
  7467. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/nvram.c linux-2.6.37/arch/mips/ar71xx/nvram.c
  7468. --- linux-2.6.37.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
  7469. +++ linux-2.6.37/arch/mips/ar71xx/nvram.c 2011-01-11 20:25:48.000000000 +0100
  7470. @@ -0,0 +1,75 @@
  7471. +/*
  7472. + * Atheros AR71xx minimal nvram support
  7473. + *
  7474. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7475. + *
  7476. + * This program is free software; you can redistribute it and/or modify it
  7477. + * under the terms of the GNU General Public License version 2 as published
  7478. + * by the Free Software Foundation.
  7479. + */
  7480. +
  7481. +#include <linux/kernel.h>
  7482. +#include <linux/vmalloc.h>
  7483. +#include <linux/errno.h>
  7484. +#include <linux/init.h>
  7485. +#include <linux/string.h>
  7486. +
  7487. +#include "nvram.h"
  7488. +
  7489. +char *nvram_find_var(const char *name, const char *buf, unsigned buf_len)
  7490. +{
  7491. + unsigned len = strlen(name);
  7492. + char *cur, *last;
  7493. +
  7494. + if (buf_len == 0 || len == 0)
  7495. + return NULL;
  7496. +
  7497. + if (buf_len < len)
  7498. + return NULL;
  7499. +
  7500. + if (len == 1)
  7501. + return memchr(buf, (int) *name, buf_len);
  7502. +
  7503. + last = (char *) buf + buf_len - len;
  7504. + for (cur = (char *) buf; cur <= last; cur++)
  7505. + if (cur[0] == name[0] && memcmp(cur, name, len) == 0)
  7506. + return cur + len;
  7507. +
  7508. + return NULL;
  7509. +}
  7510. +
  7511. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7512. + const char *name, char *mac)
  7513. +{
  7514. + char *buf;
  7515. + char *mac_str;
  7516. + int ret;
  7517. + int t;
  7518. +
  7519. + buf = vmalloc(nvram_len);
  7520. + if (!buf)
  7521. + return -ENOMEM;
  7522. +
  7523. + memcpy(buf, nvram, nvram_len);
  7524. + buf[nvram_len - 1] = '\0';
  7525. +
  7526. + mac_str = nvram_find_var(name, buf, nvram_len);
  7527. + if (!mac_str) {
  7528. + ret = -EINVAL;
  7529. + goto free;
  7530. + }
  7531. +
  7532. + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  7533. + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
  7534. +
  7535. + if (t != 6) {
  7536. + ret = -EINVAL;
  7537. + goto free;
  7538. + }
  7539. +
  7540. + ret = 0;
  7541. +
  7542. + free:
  7543. + vfree(buf);
  7544. + return ret;
  7545. +}
  7546. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/nvram.h linux-2.6.37/arch/mips/ar71xx/nvram.h
  7547. --- linux-2.6.37.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100
  7548. +++ linux-2.6.37/arch/mips/ar71xx/nvram.h 2011-01-11 20:25:48.000000000 +0100
  7549. @@ -0,0 +1,19 @@
  7550. +/*
  7551. + * Atheros AR71xx minimal nvram support
  7552. + *
  7553. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  7554. + *
  7555. + * This program is free software; you can redistribute it and/or modify it
  7556. + * under the terms of the GNU General Public License version 2 as published
  7557. + * by the Free Software Foundation.
  7558. + */
  7559. +
  7560. +#ifndef _AR71XX_NVRAM_H
  7561. +#define _AR71XX_NVRAM_H
  7562. +
  7563. +char *nvram_find_var(const char *name, const char *buf,
  7564. + unsigned buf_len) __init;
  7565. +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len,
  7566. + const char *name, char *mac) __init;
  7567. +
  7568. +#endif /* _AR71XX_NVRAM_H */
  7569. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/pci.c linux-2.6.37/arch/mips/ar71xx/pci.c
  7570. --- linux-2.6.37.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100
  7571. +++ linux-2.6.37/arch/mips/ar71xx/pci.c 2011-01-11 20:25:48.000000000 +0100
  7572. @@ -0,0 +1,93 @@
  7573. +/*
  7574. + * Atheros AR71xx PCI setup code
  7575. + *
  7576. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7577. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7578. + *
  7579. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7580. + *
  7581. + * This program is free software; you can redistribute it and/or modify it
  7582. + * under the terms of the GNU General Public License version 2 as published
  7583. + * by the Free Software Foundation.
  7584. + */
  7585. +
  7586. +#include <linux/kernel.h>
  7587. +
  7588. +#include <asm/traps.h>
  7589. +
  7590. +#include <asm/mach-ar71xx/ar71xx.h>
  7591. +#include <asm/mach-ar71xx/pci.h>
  7592. +
  7593. +unsigned ar71xx_pci_nr_irqs __initdata;
  7594. +struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  7595. +
  7596. +int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  7597. +
  7598. +static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
  7599. +{
  7600. + int err = 0;
  7601. +
  7602. + err = ar71xx_pci_be_handler(is_fixup);
  7603. +
  7604. + return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  7605. +}
  7606. +
  7607. +int pcibios_plat_dev_init(struct pci_dev *dev)
  7608. +{
  7609. + if (ar71xx_pci_plat_dev_init)
  7610. + return ar71xx_pci_plat_dev_init(dev);
  7611. +
  7612. + return 0;
  7613. +}
  7614. +
  7615. +int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
  7616. +{
  7617. + int ret = 0;
  7618. +
  7619. + switch (ar71xx_soc) {
  7620. + case AR71XX_SOC_AR7130:
  7621. + case AR71XX_SOC_AR7141:
  7622. + case AR71XX_SOC_AR7161:
  7623. + ret = ar71xx_pcibios_map_irq(dev, slot, pin);
  7624. + break;
  7625. +
  7626. + case AR71XX_SOC_AR7240:
  7627. + case AR71XX_SOC_AR7241:
  7628. + case AR71XX_SOC_AR7242:
  7629. + ret = ar724x_pcibios_map_irq(dev, slot, pin);
  7630. + break;
  7631. +
  7632. + default:
  7633. + break;
  7634. + }
  7635. +
  7636. + return ret;
  7637. +}
  7638. +
  7639. +int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
  7640. +{
  7641. + int ret = 0;
  7642. +
  7643. + switch (ar71xx_soc) {
  7644. + case AR71XX_SOC_AR7130:
  7645. + case AR71XX_SOC_AR7141:
  7646. + case AR71XX_SOC_AR7161:
  7647. + board_be_handler = ar71xx_be_handler;
  7648. + ret = ar71xx_pcibios_init();
  7649. + break;
  7650. +
  7651. + case AR71XX_SOC_AR7240:
  7652. + case AR71XX_SOC_AR7241:
  7653. + case AR71XX_SOC_AR7242:
  7654. + ret = ar724x_pcibios_init();
  7655. + break;
  7656. +
  7657. + default:
  7658. + return 0;
  7659. + }
  7660. +
  7661. + ar71xx_pci_nr_irqs = nr_irqs;
  7662. + ar71xx_pci_irq_map = map;
  7663. +
  7664. + return ret;
  7665. +}
  7666. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/prom.c linux-2.6.37/arch/mips/ar71xx/prom.c
  7667. --- linux-2.6.37.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100
  7668. +++ linux-2.6.37/arch/mips/ar71xx/prom.c 2011-01-11 20:25:48.000000000 +0100
  7669. @@ -0,0 +1,105 @@
  7670. +/*
  7671. + * Atheros AR71xx SoC specific prom routines
  7672. + *
  7673. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7674. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7675. + *
  7676. + * This program is free software; you can redistribute it and/or modify it
  7677. + * under the terms of the GNU General Public License version 2 as published
  7678. + * by the Free Software Foundation.
  7679. + */
  7680. +
  7681. +#include <linux/kernel.h>
  7682. +#include <linux/init.h>
  7683. +#include <linux/io.h>
  7684. +#include <linux/string.h>
  7685. +
  7686. +#include <asm/bootinfo.h>
  7687. +#include <asm/addrspace.h>
  7688. +
  7689. +#include <asm/mach-ar71xx/ar71xx.h>
  7690. +
  7691. +static inline int is_valid_ram_addr(void *addr)
  7692. +{
  7693. + if (((u32) addr > KSEG0) &&
  7694. + ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX)))
  7695. + return 1;
  7696. +
  7697. + if (((u32) addr > KSEG1) &&
  7698. + ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX)))
  7699. + return 1;
  7700. +
  7701. + return 0;
  7702. +}
  7703. +
  7704. +static void __init ar71xx_prom_append_cmdline(const char *name,
  7705. + const char *value)
  7706. +{
  7707. + char buf[COMMAND_LINE_SIZE];
  7708. +
  7709. + snprintf(buf, sizeof(buf), " %s=%s", name, value);
  7710. + strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline));
  7711. +}
  7712. +
  7713. +static void __init ar71xx_prom_find_env(char **envp, const char *name)
  7714. +{
  7715. + int len = strlen(name);
  7716. + char **p;
  7717. +
  7718. + if (!is_valid_ram_addr(envp))
  7719. + return;
  7720. +
  7721. + for (p = envp; is_valid_ram_addr(*p); p++) {
  7722. + if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') {
  7723. + ar71xx_prom_append_cmdline(name, *p + len + 1);
  7724. + break;
  7725. + }
  7726. +
  7727. + /* RedBoot env comes in pointer pairs - key, value */
  7728. + if (strncmp(name, *p, len) == 0 && (*p)[len] == 0)
  7729. + if (is_valid_ram_addr(*(++p))) {
  7730. + ar71xx_prom_append_cmdline(name, *p);
  7731. + break;
  7732. + }
  7733. + }
  7734. +}
  7735. +
  7736. +static int inline ar71xx_use__image_cmdline(void) { return 0; }
  7737. +
  7738. +static __init void ar71xx_prom_init_cmdline(int argc, char **argv)
  7739. +{
  7740. + int i;
  7741. +
  7742. + if (ar71xx_use__image_cmdline())
  7743. + return;
  7744. +
  7745. + if (!is_valid_ram_addr(argv))
  7746. + return;
  7747. +
  7748. + for (i = 0; i < argc; i++)
  7749. + if (is_valid_ram_addr(argv[i])) {
  7750. + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
  7751. + strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
  7752. + }
  7753. +}
  7754. +
  7755. +void __init prom_init(void)
  7756. +{
  7757. + char **envp;
  7758. +
  7759. + printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, "
  7760. + "fw_arg2=%08x, fw_arg3=%08x\n",
  7761. + (unsigned int)fw_arg0, (unsigned int)fw_arg1,
  7762. + (unsigned int)fw_arg2, (unsigned int)fw_arg3);
  7763. +
  7764. +
  7765. + ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
  7766. +
  7767. + envp = (char **)fw_arg2;
  7768. + ar71xx_prom_find_env(envp, "board");
  7769. +}
  7770. +
  7771. +void __init prom_free_prom_memory(void)
  7772. +{
  7773. + /* We do not have to prom memory to free */
  7774. +}
  7775. diff -Nur linux-2.6.37.orig/arch/mips/ar71xx/setup.c linux-2.6.37/arch/mips/ar71xx/setup.c
  7776. --- linux-2.6.37.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100
  7777. +++ linux-2.6.37/arch/mips/ar71xx/setup.c 2011-01-11 20:25:48.000000000 +0100
  7778. @@ -0,0 +1,310 @@
  7779. +/*
  7780. + * Atheros AR71xx SoC specific setup
  7781. + *
  7782. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  7783. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  7784. + *
  7785. + * Parts of this file are based on Atheros' 2.6.15 BSP
  7786. + *
  7787. + * This program is free software; you can redistribute it and/or modify it
  7788. + * under the terms of the GNU General Public License version 2 as published
  7789. + * by the Free Software Foundation.
  7790. + */
  7791. +
  7792. +#include <linux/kernel.h>
  7793. +#include <linux/init.h>
  7794. +#include <linux/bootmem.h>
  7795. +
  7796. +#include <asm/bootinfo.h>
  7797. +#include <asm/time.h> /* for mips_hpt_frequency */
  7798. +#include <asm/reboot.h> /* for _machine_{restart,halt} */
  7799. +#include <asm/mips_machine.h>
  7800. +
  7801. +#include <asm/mach-ar71xx/ar71xx.h>
  7802. +
  7803. +#include "machtype.h"
  7804. +#include "devices.h"
  7805. +
  7806. +#define AR71XX_SYS_TYPE_LEN 64
  7807. +#define AR71XX_BASE_FREQ 40000000
  7808. +#define AR91XX_BASE_FREQ 5000000
  7809. +#define AR724X_BASE_FREQ 5000000
  7810. +
  7811. +u32 ar71xx_cpu_freq;
  7812. +EXPORT_SYMBOL_GPL(ar71xx_cpu_freq);
  7813. +
  7814. +u32 ar71xx_ahb_freq;
  7815. +EXPORT_SYMBOL_GPL(ar71xx_ahb_freq);
  7816. +
  7817. +u32 ar71xx_ddr_freq;
  7818. +EXPORT_SYMBOL_GPL(ar71xx_ddr_freq);
  7819. +
  7820. +enum ar71xx_soc_type ar71xx_soc;
  7821. +EXPORT_SYMBOL_GPL(ar71xx_soc);
  7822. +
  7823. +static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];
  7824. +
  7825. +static void ar71xx_restart(char *command)
  7826. +{
  7827. + ar71xx_device_stop(RESET_MODULE_FULL_CHIP);
  7828. + for (;;)
  7829. + if (cpu_wait)
  7830. + cpu_wait();
  7831. +}
  7832. +
  7833. +static void ar71xx_halt(void)
  7834. +{
  7835. + while (1)
  7836. + cpu_wait();
  7837. +}
  7838. +
  7839. +static void __init ar71xx_detect_mem_size(void)
  7840. +{
  7841. + unsigned long size;
  7842. +
  7843. + for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX;
  7844. + size <<= 1 ) {
  7845. + if (!memcmp(ar71xx_detect_mem_size,
  7846. + ar71xx_detect_mem_size + size, 1024))
  7847. + break;
  7848. + }
  7849. +
  7850. + add_memory_region(0, size, BOOT_MEM_RAM);
  7851. +}
  7852. +
  7853. +static void __init ar71xx_detect_sys_type(void)
  7854. +{
  7855. + char *chip = "????";
  7856. + u32 id;
  7857. + u32 major;
  7858. + u32 minor;
  7859. + u32 rev = 0;
  7860. +
  7861. + id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID);
  7862. + major = id & REV_ID_MAJOR_MASK;
  7863. +
  7864. + switch (major) {
  7865. + case REV_ID_MAJOR_AR71XX:
  7866. + minor = id & AR71XX_REV_ID_MINOR_MASK;
  7867. + rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
  7868. + rev &= AR71XX_REV_ID_REVISION_MASK;
  7869. + switch (minor) {
  7870. + case AR71XX_REV_ID_MINOR_AR7130:
  7871. + ar71xx_soc = AR71XX_SOC_AR7130;
  7872. + chip = "7130";
  7873. + break;
  7874. +
  7875. + case AR71XX_REV_ID_MINOR_AR7141:
  7876. + ar71xx_soc = AR71XX_SOC_AR7141;
  7877. + chip = "7141";
  7878. + break;
  7879. +
  7880. + case AR71XX_REV_ID_MINOR_AR7161:
  7881. + ar71xx_soc = AR71XX_SOC_AR7161;
  7882. + chip = "7161";
  7883. + break;
  7884. + }
  7885. + break;
  7886. +
  7887. + case REV_ID_MAJOR_AR7240:
  7888. + ar71xx_soc = AR71XX_SOC_AR7240;
  7889. + chip = "7240";
  7890. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7891. + break;
  7892. +
  7893. + case REV_ID_MAJOR_AR7241:
  7894. + ar71xx_soc = AR71XX_SOC_AR7241;
  7895. + chip = "7241";
  7896. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7897. + break;
  7898. +
  7899. + case REV_ID_MAJOR_AR7242:
  7900. + ar71xx_soc = AR71XX_SOC_AR7242;
  7901. + chip = "7242";
  7902. + rev = (id & AR724X_REV_ID_REVISION_MASK);
  7903. + break;
  7904. +
  7905. + case REV_ID_MAJOR_AR913X:
  7906. + minor = id & AR91XX_REV_ID_MINOR_MASK;
  7907. + rev = id >> AR91XX_REV_ID_REVISION_SHIFT;
  7908. + rev &= AR91XX_REV_ID_REVISION_MASK;
  7909. + switch (minor) {
  7910. + case AR91XX_REV_ID_MINOR_AR9130:
  7911. + ar71xx_soc = AR71XX_SOC_AR9130;
  7912. + chip = "9130";
  7913. + break;
  7914. +
  7915. + case AR91XX_REV_ID_MINOR_AR9132:
  7916. + ar71xx_soc = AR71XX_SOC_AR9132;
  7917. + chip = "9132";
  7918. + break;
  7919. + }
  7920. + break;
  7921. +
  7922. + default:
  7923. + panic("ar71xx: unknown chip id:0x%08x\n", id);
  7924. + }
  7925. +
  7926. + sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev);
  7927. +}
  7928. +
  7929. +static void __init ar91xx_detect_sys_frequency(void)
  7930. +{
  7931. + u32 pll;
  7932. + u32 freq;
  7933. + u32 div;
  7934. +
  7935. + pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
  7936. +
  7937. + div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
  7938. + freq = div * AR91XX_BASE_FREQ;
  7939. +
  7940. + ar71xx_cpu_freq = freq;
  7941. +
  7942. + div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1;
  7943. + ar71xx_ddr_freq = freq / div;
  7944. +
  7945. + div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2;
  7946. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7947. +}
  7948. +
  7949. +static void __init ar71xx_detect_sys_frequency(void)
  7950. +{
  7951. + u32 pll;
  7952. + u32 freq;
  7953. + u32 div;
  7954. +
  7955. + pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
  7956. +
  7957. + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
  7958. + freq = div * AR71XX_BASE_FREQ;
  7959. +
  7960. + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
  7961. + ar71xx_cpu_freq = freq / div;
  7962. +
  7963. + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
  7964. + ar71xx_ddr_freq = freq / div;
  7965. +
  7966. + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
  7967. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7968. +}
  7969. +
  7970. +static void __init ar724x_detect_sys_frequency(void)
  7971. +{
  7972. + u32 pll;
  7973. + u32 freq;
  7974. + u32 div;
  7975. +
  7976. + pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
  7977. +
  7978. + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
  7979. + freq = div * AR724X_BASE_FREQ;
  7980. +
  7981. + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
  7982. + freq *= div;
  7983. +
  7984. + ar71xx_cpu_freq = freq;
  7985. +
  7986. + div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
  7987. + ar71xx_ddr_freq = freq / div;
  7988. +
  7989. + div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
  7990. + ar71xx_ahb_freq = ar71xx_cpu_freq / div;
  7991. +}
  7992. +
  7993. +static void __init detect_sys_frequency(void)
  7994. +{
  7995. + switch (ar71xx_soc) {
  7996. + case AR71XX_SOC_AR7130:
  7997. + case AR71XX_SOC_AR7141:
  7998. + case AR71XX_SOC_AR7161:
  7999. + ar71xx_detect_sys_frequency();
  8000. + break;
  8001. +
  8002. + case AR71XX_SOC_AR7240:
  8003. + case AR71XX_SOC_AR7241:
  8004. + case AR71XX_SOC_AR7242:
  8005. + ar724x_detect_sys_frequency();
  8006. + break;
  8007. +
  8008. + case AR71XX_SOC_AR9130:
  8009. + case AR71XX_SOC_AR9132:
  8010. + ar91xx_detect_sys_frequency();
  8011. + break;
  8012. +
  8013. + default:
  8014. + BUG();
  8015. + }
  8016. +}
  8017. +
  8018. +const char *get_system_type(void)
  8019. +{
  8020. + return ar71xx_sys_type;
  8021. +}
  8022. +
  8023. +unsigned int __cpuinit get_c0_compare_irq(void)
  8024. +{
  8025. + return CP0_LEGACY_COMPARE_IRQ;
  8026. +}
  8027. +
  8028. +void __init plat_mem_setup(void)
  8029. +{
  8030. + set_io_port_base(KSEG1);
  8031. +
  8032. + ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
  8033. + AR71XX_DDR_CTRL_SIZE);
  8034. +
  8035. + ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
  8036. + AR71XX_PLL_SIZE);
  8037. +
  8038. + ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
  8039. + AR71XX_RESET_SIZE);
  8040. +
  8041. + ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
  8042. +
  8043. + ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE,
  8044. + AR71XX_USB_CTRL_SIZE);
  8045. +
  8046. + ar71xx_detect_mem_size();
  8047. + ar71xx_detect_sys_type();
  8048. + detect_sys_frequency();
  8049. +
  8050. + printk(KERN_INFO
  8051. + "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n",
  8052. + ar71xx_sys_type,
  8053. + ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000,
  8054. + ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000,
  8055. + ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000);
  8056. +
  8057. + _machine_restart = ar71xx_restart;
  8058. + _machine_halt = ar71xx_halt;
  8059. + pm_power_off = ar71xx_halt;
  8060. +}
  8061. +
  8062. +void __init plat_time_init(void)
  8063. +{
  8064. + mips_hpt_frequency = ar71xx_cpu_freq / 2;
  8065. +}
  8066. +
  8067. +__setup("board=", mips_machtype_setup);
  8068. +
  8069. +static int __init ar71xx_machine_setup(void)
  8070. +{
  8071. + ar71xx_gpio_init();
  8072. +
  8073. + ar71xx_add_device_uart();
  8074. + ar71xx_add_device_wdt();
  8075. +
  8076. + mips_machine_setup();
  8077. + return 0;
  8078. +}
  8079. +
  8080. +arch_initcall(ar71xx_machine_setup);
  8081. +
  8082. +static void __init ar71xx_generic_init(void)
  8083. +{
  8084. + /* Nothing to do */
  8085. +}
  8086. +
  8087. +MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board",
  8088. + ar71xx_generic_init);
  8089. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/ar71xx.h
  8090. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100
  8091. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-01-11 20:25:48.000000000 +0100
  8092. @@ -0,0 +1,514 @@
  8093. +/*
  8094. + * Atheros AR71xx SoC specific definitions
  8095. + *
  8096. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8097. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8098. + *
  8099. + * Parts of this file are based on Atheros' 2.6.15 BSP
  8100. + *
  8101. + * This program is free software; you can redistribute it and/or modify it
  8102. + * under the terms of the GNU General Public License version 2 as published
  8103. + * by the Free Software Foundation.
  8104. + */
  8105. +
  8106. +#ifndef __ASM_MACH_AR71XX_H
  8107. +#define __ASM_MACH_AR71XX_H
  8108. +
  8109. +#include <linux/types.h>
  8110. +#include <linux/init.h>
  8111. +#include <linux/io.h>
  8112. +#include <linux/bitops.h>
  8113. +
  8114. +#ifndef __ASSEMBLER__
  8115. +
  8116. +#define AR71XX_PCI_MEM_BASE 0x10000000
  8117. +#define AR71XX_PCI_MEM_SIZE 0x08000000
  8118. +#define AR71XX_APB_BASE 0x18000000
  8119. +#define AR71XX_GE0_BASE 0x19000000
  8120. +#define AR71XX_GE0_SIZE 0x01000000
  8121. +#define AR71XX_GE1_BASE 0x1a000000
  8122. +#define AR71XX_GE1_SIZE 0x01000000
  8123. +#define AR71XX_EHCI_BASE 0x1b000000
  8124. +#define AR71XX_EHCI_SIZE 0x01000000
  8125. +#define AR71XX_OHCI_BASE 0x1c000000
  8126. +#define AR71XX_OHCI_SIZE 0x01000000
  8127. +#define AR7240_OHCI_BASE 0x1b000000
  8128. +#define AR7240_OHCI_SIZE 0x01000000
  8129. +#define AR71XX_SPI_BASE 0x1f000000
  8130. +#define AR71XX_SPI_SIZE 0x01000000
  8131. +
  8132. +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
  8133. +#define AR71XX_DDR_CTRL_SIZE 0x10000
  8134. +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
  8135. +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
  8136. +#define AR71XX_UART_SIZE 0x10000
  8137. +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
  8138. +#define AR71XX_USB_CTRL_SIZE 0x10000
  8139. +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
  8140. +#define AR71XX_GPIO_SIZE 0x10000
  8141. +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
  8142. +#define AR71XX_PLL_SIZE 0x10000
  8143. +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
  8144. +#define AR71XX_RESET_SIZE 0x10000
  8145. +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
  8146. +#define AR71XX_MII_SIZE 0x10000
  8147. +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
  8148. +#define AR71XX_SLIC_SIZE 0x10000
  8149. +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
  8150. +#define AR71XX_DMA_SIZE 0x10000
  8151. +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
  8152. +#define AR71XX_STEREO_SIZE 0x10000
  8153. +
  8154. +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
  8155. +#define AR724X_PCI_CRP_SIZE 0x100
  8156. +
  8157. +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
  8158. +#define AR724X_PCI_CTRL_SIZE 0x100
  8159. +
  8160. +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
  8161. +#define AR91XX_WMAC_SIZE 0x30000
  8162. +
  8163. +#define AR71XX_MEM_SIZE_MIN 0x0200000
  8164. +#define AR71XX_MEM_SIZE_MAX 0x10000000
  8165. +
  8166. +#define AR71XX_CPU_IRQ_BASE 0
  8167. +#define AR71XX_MISC_IRQ_BASE 8
  8168. +#define AR71XX_MISC_IRQ_COUNT 8
  8169. +#define AR71XX_GPIO_IRQ_BASE 16
  8170. +#define AR71XX_GPIO_IRQ_COUNT 32
  8171. +#define AR71XX_PCI_IRQ_BASE 48
  8172. +#define AR71XX_PCI_IRQ_COUNT 8
  8173. +
  8174. +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
  8175. +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
  8176. +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
  8177. +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
  8178. +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
  8179. +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
  8180. +
  8181. +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
  8182. +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
  8183. +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
  8184. +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
  8185. +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
  8186. +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
  8187. +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
  8188. +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
  8189. +
  8190. +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
  8191. +
  8192. +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
  8193. +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
  8194. +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
  8195. +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
  8196. +
  8197. +extern u32 ar71xx_ahb_freq;
  8198. +extern u32 ar71xx_cpu_freq;
  8199. +extern u32 ar71xx_ddr_freq;
  8200. +
  8201. +enum ar71xx_soc_type {
  8202. + AR71XX_SOC_UNKNOWN,
  8203. + AR71XX_SOC_AR7130,
  8204. + AR71XX_SOC_AR7141,
  8205. + AR71XX_SOC_AR7161,
  8206. + AR71XX_SOC_AR7240,
  8207. + AR71XX_SOC_AR7241,
  8208. + AR71XX_SOC_AR7242,
  8209. + AR71XX_SOC_AR9130,
  8210. + AR71XX_SOC_AR9132
  8211. +};
  8212. +
  8213. +extern enum ar71xx_soc_type ar71xx_soc;
  8214. +
  8215. +/*
  8216. + * PLL block
  8217. + */
  8218. +#define AR71XX_PLL_REG_CPU_CONFIG 0x00
  8219. +#define AR71XX_PLL_REG_SEC_CONFIG 0x04
  8220. +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
  8221. +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
  8222. +
  8223. +#define AR71XX_PLL_DIV_SHIFT 3
  8224. +#define AR71XX_PLL_DIV_MASK 0x1f
  8225. +#define AR71XX_CPU_DIV_SHIFT 16
  8226. +#define AR71XX_CPU_DIV_MASK 0x3
  8227. +#define AR71XX_DDR_DIV_SHIFT 18
  8228. +#define AR71XX_DDR_DIV_MASK 0x3
  8229. +#define AR71XX_AHB_DIV_SHIFT 20
  8230. +#define AR71XX_AHB_DIV_MASK 0x7
  8231. +
  8232. +#define AR71XX_ETH0_PLL_SHIFT 17
  8233. +#define AR71XX_ETH1_PLL_SHIFT 19
  8234. +
  8235. +#define AR724X_PLL_REG_CPU_CONFIG 0x00
  8236. +#define AR724X_PLL_REG_PCIE_CONFIG 0x18
  8237. +
  8238. +#define AR724X_PLL_DIV_SHIFT 0
  8239. +#define AR724X_PLL_DIV_MASK 0x3ff
  8240. +#define AR724X_PLL_REF_DIV_SHIFT 10
  8241. +#define AR724X_PLL_REF_DIV_MASK 0xf
  8242. +#define AR724X_AHB_DIV_SHIFT 19
  8243. +#define AR724X_AHB_DIV_MASK 0x1
  8244. +#define AR724X_DDR_DIV_SHIFT 22
  8245. +#define AR724X_DDR_DIV_MASK 0x3
  8246. +
  8247. +#define AR91XX_PLL_REG_CPU_CONFIG 0x00
  8248. +#define AR91XX_PLL_REG_ETH_CONFIG 0x04
  8249. +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
  8250. +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
  8251. +
  8252. +#define AR91XX_PLL_DIV_SHIFT 0
  8253. +#define AR91XX_PLL_DIV_MASK 0x3ff
  8254. +#define AR91XX_DDR_DIV_SHIFT 22
  8255. +#define AR91XX_DDR_DIV_MASK 0x3
  8256. +#define AR91XX_AHB_DIV_SHIFT 19
  8257. +#define AR91XX_AHB_DIV_MASK 0x1
  8258. +
  8259. +#define AR91XX_ETH0_PLL_SHIFT 20
  8260. +#define AR91XX_ETH1_PLL_SHIFT 22
  8261. +
  8262. +extern void __iomem *ar71xx_pll_base;
  8263. +
  8264. +static inline void ar71xx_pll_wr(unsigned reg, u32 val)
  8265. +{
  8266. + __raw_writel(val, ar71xx_pll_base + reg);
  8267. +}
  8268. +
  8269. +static inline u32 ar71xx_pll_rr(unsigned reg)
  8270. +{
  8271. + return __raw_readl(ar71xx_pll_base + reg);
  8272. +}
  8273. +
  8274. +/*
  8275. + * USB_CONFIG block
  8276. + */
  8277. +#define USB_CTRL_REG_FLADJ 0x00
  8278. +#define USB_CTRL_REG_CONFIG 0x04
  8279. +
  8280. +extern void __iomem *ar71xx_usb_ctrl_base;
  8281. +
  8282. +static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
  8283. +{
  8284. + __raw_writel(val, ar71xx_usb_ctrl_base + reg);
  8285. +}
  8286. +
  8287. +static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
  8288. +{
  8289. + return __raw_readl(ar71xx_usb_ctrl_base + reg);
  8290. +}
  8291. +
  8292. +/*
  8293. + * GPIO block
  8294. + */
  8295. +#define GPIO_REG_OE 0x00
  8296. +#define GPIO_REG_IN 0x04
  8297. +#define GPIO_REG_OUT 0x08
  8298. +#define GPIO_REG_SET 0x0c
  8299. +#define GPIO_REG_CLEAR 0x10
  8300. +#define GPIO_REG_INT_MODE 0x14
  8301. +#define GPIO_REG_INT_TYPE 0x18
  8302. +#define GPIO_REG_INT_POLARITY 0x1c
  8303. +#define GPIO_REG_INT_PENDING 0x20
  8304. +#define GPIO_REG_INT_ENABLE 0x24
  8305. +#define GPIO_REG_FUNC 0x28
  8306. +
  8307. +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
  8308. +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
  8309. +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
  8310. +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
  8311. +#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
  8312. +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
  8313. +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
  8314. +
  8315. +#define AR71XX_GPIO_COUNT 16
  8316. +
  8317. +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
  8318. +#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
  8319. +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
  8320. +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
  8321. +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
  8322. +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
  8323. +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
  8324. +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
  8325. +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
  8326. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
  8327. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
  8328. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
  8329. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
  8330. +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
  8331. +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
  8332. +#define AR724X_GPIO_FUNC_UART_EN BIT(1)
  8333. +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
  8334. +
  8335. +#define AR724X_GPIO_COUNT 18
  8336. +
  8337. +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
  8338. +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
  8339. +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
  8340. +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
  8341. +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
  8342. +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
  8343. +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
  8344. +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
  8345. +#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
  8346. +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
  8347. +
  8348. +#define AR91XX_GPIO_COUNT 22
  8349. +
  8350. +extern void __iomem *ar71xx_gpio_base;
  8351. +
  8352. +static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
  8353. +{
  8354. + __raw_writel(value, ar71xx_gpio_base + reg);
  8355. +}
  8356. +
  8357. +static inline u32 ar71xx_gpio_rr(unsigned reg)
  8358. +{
  8359. + return __raw_readl(ar71xx_gpio_base + reg);
  8360. +}
  8361. +
  8362. +void ar71xx_gpio_init(void) __init;
  8363. +void ar71xx_gpio_function_enable(u32 mask);
  8364. +void ar71xx_gpio_function_disable(u32 mask);
  8365. +void ar71xx_gpio_function_setup(u32 set, u32 clear);
  8366. +
  8367. +/*
  8368. + * DDR_CTRL block
  8369. + */
  8370. +#define AR71XX_DDR_REG_PCI_WIN0 0x7c
  8371. +#define AR71XX_DDR_REG_PCI_WIN1 0x80
  8372. +#define AR71XX_DDR_REG_PCI_WIN2 0x84
  8373. +#define AR71XX_DDR_REG_PCI_WIN3 0x88
  8374. +#define AR71XX_DDR_REG_PCI_WIN4 0x8c
  8375. +#define AR71XX_DDR_REG_PCI_WIN5 0x90
  8376. +#define AR71XX_DDR_REG_PCI_WIN6 0x94
  8377. +#define AR71XX_DDR_REG_PCI_WIN7 0x98
  8378. +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
  8379. +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
  8380. +#define AR71XX_DDR_REG_FLUSH_USB 0xa4
  8381. +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
  8382. +
  8383. +#define AR724X_DDR_REG_FLUSH_GE0 0x7c
  8384. +#define AR724X_DDR_REG_FLUSH_GE1 0x80
  8385. +#define AR724X_DDR_REG_FLUSH_USB 0x84
  8386. +#define AR724X_DDR_REG_FLUSH_PCIE 0x88
  8387. +
  8388. +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
  8389. +#define AR91XX_DDR_REG_FLUSH_GE1 0x80
  8390. +#define AR91XX_DDR_REG_FLUSH_USB 0x84
  8391. +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
  8392. +
  8393. +#define PCI_WIN0_OFFS 0x10000000
  8394. +#define PCI_WIN1_OFFS 0x11000000
  8395. +#define PCI_WIN2_OFFS 0x12000000
  8396. +#define PCI_WIN3_OFFS 0x13000000
  8397. +#define PCI_WIN4_OFFS 0x14000000
  8398. +#define PCI_WIN5_OFFS 0x15000000
  8399. +#define PCI_WIN6_OFFS 0x16000000
  8400. +#define PCI_WIN7_OFFS 0x07000000
  8401. +
  8402. +extern void __iomem *ar71xx_ddr_base;
  8403. +
  8404. +static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
  8405. +{
  8406. + __raw_writel(val, ar71xx_ddr_base + reg);
  8407. +}
  8408. +
  8409. +static inline u32 ar71xx_ddr_rr(unsigned reg)
  8410. +{
  8411. + return __raw_readl(ar71xx_ddr_base + reg);
  8412. +}
  8413. +
  8414. +void ar71xx_ddr_flush(u32 reg);
  8415. +
  8416. +/*
  8417. + * PCI block
  8418. + */
  8419. +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
  8420. +#define AR71XX_PCI_CFG_SIZE 0x100
  8421. +
  8422. +#define PCI_REG_CRP_AD_CBE 0x00
  8423. +#define PCI_REG_CRP_WRDATA 0x04
  8424. +#define PCI_REG_CRP_RDDATA 0x08
  8425. +#define PCI_REG_CFG_AD 0x0c
  8426. +#define PCI_REG_CFG_CBE 0x10
  8427. +#define PCI_REG_CFG_WRDATA 0x14
  8428. +#define PCI_REG_CFG_RDDATA 0x18
  8429. +#define PCI_REG_PCI_ERR 0x1c
  8430. +#define PCI_REG_PCI_ERR_ADDR 0x20
  8431. +#define PCI_REG_AHB_ERR 0x24
  8432. +#define PCI_REG_AHB_ERR_ADDR 0x28
  8433. +
  8434. +#define PCI_CRP_CMD_WRITE 0x00010000
  8435. +#define PCI_CRP_CMD_READ 0x00000000
  8436. +#define PCI_CFG_CMD_READ 0x0000000a
  8437. +#define PCI_CFG_CMD_WRITE 0x0000000b
  8438. +
  8439. +#define PCI_IDSEL_ADL_START 17
  8440. +
  8441. +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
  8442. +#define AR724X_PCI_CFG_SIZE 0x1000
  8443. +
  8444. +#define AR724X_PCI_REG_APP 0x00
  8445. +#define AR724X_PCI_REG_RESET 0x18
  8446. +#define AR724X_PCI_REG_INT_STATUS 0x4c
  8447. +#define AR724X_PCI_REG_INT_MASK 0x50
  8448. +
  8449. +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
  8450. +#define AR724X_PCI_RESET_LINK_UP BIT(0)
  8451. +
  8452. +#define AR724X_PCI_INT_DEV0 BIT(14)
  8453. +
  8454. +/*
  8455. + * RESET block
  8456. + */
  8457. +#define AR71XX_RESET_REG_TIMER 0x00
  8458. +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
  8459. +#define AR71XX_RESET_REG_WDOG_CTRL 0x08
  8460. +#define AR71XX_RESET_REG_WDOG 0x0c
  8461. +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
  8462. +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
  8463. +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
  8464. +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
  8465. +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
  8466. +#define AR71XX_RESET_REG_RESET_MODULE 0x24
  8467. +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
  8468. +#define AR71XX_RESET_REG_PERFC0 0x30
  8469. +#define AR71XX_RESET_REG_PERFC1 0x34
  8470. +#define AR71XX_RESET_REG_REV_ID 0x90
  8471. +
  8472. +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
  8473. +#define AR91XX_RESET_REG_RESET_MODULE 0x1c
  8474. +#define AR91XX_RESET_REG_PERF_CTRL 0x20
  8475. +#define AR91XX_RESET_REG_PERFC0 0x24
  8476. +#define AR91XX_RESET_REG_PERFC1 0x28
  8477. +
  8478. +#define AR724X_RESET_REG_RESET_MODULE 0x1c
  8479. +
  8480. +#define WDOG_CTRL_LAST_RESET BIT(31)
  8481. +#define WDOG_CTRL_ACTION_MASK 3
  8482. +#define WDOG_CTRL_ACTION_NONE 0 /* no action */
  8483. +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
  8484. +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
  8485. +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
  8486. +
  8487. +#define MISC_INT_DMA BIT(7)
  8488. +#define MISC_INT_OHCI BIT(6)
  8489. +#define MISC_INT_PERFC BIT(5)
  8490. +#define MISC_INT_WDOG BIT(4)
  8491. +#define MISC_INT_UART BIT(3)
  8492. +#define MISC_INT_GPIO BIT(2)
  8493. +#define MISC_INT_ERROR BIT(1)
  8494. +#define MISC_INT_TIMER BIT(0)
  8495. +
  8496. +#define PCI_INT_CORE BIT(4)
  8497. +#define PCI_INT_DEV2 BIT(2)
  8498. +#define PCI_INT_DEV1 BIT(1)
  8499. +#define PCI_INT_DEV0 BIT(0)
  8500. +
  8501. +#define RESET_MODULE_EXTERNAL BIT(28)
  8502. +#define RESET_MODULE_FULL_CHIP BIT(24)
  8503. +#define RESET_MODULE_AMBA2WMAC BIT(22)
  8504. +#define RESET_MODULE_CPU_NMI BIT(21)
  8505. +#define RESET_MODULE_CPU_COLD BIT(20)
  8506. +#define RESET_MODULE_DMA BIT(19)
  8507. +#define RESET_MODULE_SLIC BIT(18)
  8508. +#define RESET_MODULE_STEREO BIT(17)
  8509. +#define RESET_MODULE_DDR BIT(16)
  8510. +#define RESET_MODULE_GE1_MAC BIT(13)
  8511. +#define RESET_MODULE_GE1_PHY BIT(12)
  8512. +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
  8513. +#define RESET_MODULE_GE0_MAC BIT(9)
  8514. +#define RESET_MODULE_GE0_PHY BIT(8)
  8515. +#define RESET_MODULE_USB_OHCI_DLL BIT(6)
  8516. +#define RESET_MODULE_USB_HOST BIT(5)
  8517. +#define RESET_MODULE_USB_PHY BIT(4)
  8518. +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
  8519. +#define RESET_MODULE_PCI_BUS BIT(1)
  8520. +#define RESET_MODULE_PCI_CORE BIT(0)
  8521. +
  8522. +#define AR724X_RESET_GE1_MDIO BIT(23)
  8523. +#define AR724X_RESET_GE0_MDIO BIT(22)
  8524. +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
  8525. +#define AR724X_RESET_PCIE_PHY BIT(7)
  8526. +#define AR724X_RESET_PCIE BIT(6)
  8527. +
  8528. +#define REV_ID_MAJOR_MASK 0xfff0
  8529. +#define REV_ID_MAJOR_AR71XX 0x00a0
  8530. +#define REV_ID_MAJOR_AR913X 0x00b0
  8531. +#define REV_ID_MAJOR_AR7240 0x00c0
  8532. +#define REV_ID_MAJOR_AR7241 0x0100
  8533. +#define REV_ID_MAJOR_AR7242 0x1100
  8534. +
  8535. +#define AR71XX_REV_ID_MINOR_MASK 0x3
  8536. +#define AR71XX_REV_ID_MINOR_AR7130 0x0
  8537. +#define AR71XX_REV_ID_MINOR_AR7141 0x1
  8538. +#define AR71XX_REV_ID_MINOR_AR7161 0x2
  8539. +#define AR71XX_REV_ID_REVISION_MASK 0x3
  8540. +#define AR71XX_REV_ID_REVISION_SHIFT 2
  8541. +
  8542. +#define AR91XX_REV_ID_MINOR_MASK 0x3
  8543. +#define AR91XX_REV_ID_MINOR_AR9130 0x0
  8544. +#define AR91XX_REV_ID_MINOR_AR9132 0x1
  8545. +#define AR91XX_REV_ID_REVISION_MASK 0x3
  8546. +#define AR91XX_REV_ID_REVISION_SHIFT 2
  8547. +
  8548. +#define AR724X_REV_ID_REVISION_MASK 0x3
  8549. +
  8550. +extern void __iomem *ar71xx_reset_base;
  8551. +
  8552. +static inline void ar71xx_reset_wr(unsigned reg, u32 val)
  8553. +{
  8554. + __raw_writel(val, ar71xx_reset_base + reg);
  8555. +}
  8556. +
  8557. +static inline u32 ar71xx_reset_rr(unsigned reg)
  8558. +{
  8559. + return __raw_readl(ar71xx_reset_base + reg);
  8560. +}
  8561. +
  8562. +void ar71xx_device_stop(u32 mask);
  8563. +void ar71xx_device_start(u32 mask);
  8564. +int ar71xx_device_stopped(u32 mask);
  8565. +
  8566. +/*
  8567. + * SPI block
  8568. + */
  8569. +#define SPI_REG_FS 0x00 /* Function Select */
  8570. +#define SPI_REG_CTRL 0x04 /* SPI Control */
  8571. +#define SPI_REG_IOC 0x08 /* SPI I/O Control */
  8572. +#define SPI_REG_RDS 0x0c /* Read Data Shift */
  8573. +
  8574. +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
  8575. +
  8576. +#define SPI_CTRL_RD BIT(6) /* Remap Disable */
  8577. +#define SPI_CTRL_DIV_MASK 0x3f
  8578. +
  8579. +#define SPI_IOC_DO BIT(0) /* Data Out pin */
  8580. +#define SPI_IOC_CLK BIT(8) /* CLK pin */
  8581. +#define SPI_IOC_CS(n) BIT(16 + (n))
  8582. +#define SPI_IOC_CS0 SPI_IOC_CS(0)
  8583. +#define SPI_IOC_CS1 SPI_IOC_CS(1)
  8584. +#define SPI_IOC_CS2 SPI_IOC_CS(2)
  8585. +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
  8586. +
  8587. +void ar71xx_flash_acquire(void);
  8588. +void ar71xx_flash_release(void);
  8589. +
  8590. +/*
  8591. + * MII_CTRL block
  8592. + */
  8593. +#define MII_REG_MII0_CTRL 0x00
  8594. +#define MII_REG_MII1_CTRL 0x04
  8595. +
  8596. +#define MII0_CTRL_IF_GMII 0
  8597. +#define MII0_CTRL_IF_MII 1
  8598. +#define MII0_CTRL_IF_RGMII 2
  8599. +#define MII0_CTRL_IF_RMII 3
  8600. +
  8601. +#define MII1_CTRL_IF_RGMII 0
  8602. +#define MII1_CTRL_IF_RMII 1
  8603. +
  8604. +#endif /* __ASSEMBLER__ */
  8605. +
  8606. +#endif /* __ASM_MACH_AR71XX_H */
  8607. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h
  8608. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100
  8609. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-01-11 20:25:48.000000000 +0100
  8610. @@ -0,0 +1,26 @@
  8611. +/*
  8612. + * AR91xx parallel flash driver platform data definitions
  8613. + *
  8614. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8615. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8616. + *
  8617. + * This program is free software; you can redistribute it and/or modify it
  8618. + * under the terms of the GNU General Public License version 2 as published
  8619. + * by the Free Software Foundation.
  8620. + */
  8621. +
  8622. +#ifndef __AR91XX_FLASH_H
  8623. +#define __AR91XX_FLASH_H
  8624. +
  8625. +struct mtd_partition;
  8626. +
  8627. +struct ar91xx_flash_platform_data {
  8628. + unsigned int width;
  8629. + u8 is_shared:1;
  8630. +#ifdef CONFIG_MTD_PARTITIONS
  8631. + unsigned int nr_parts;
  8632. + struct mtd_partition *parts;
  8633. +#endif
  8634. +};
  8635. +
  8636. +#endif /* __AR91XX_FLASH_H */
  8637. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h
  8638. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100
  8639. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-01-11 20:25:48.000000000 +0100
  8640. @@ -0,0 +1,56 @@
  8641. +/*
  8642. + * Atheros AR71xx specific CPU feature overrides
  8643. + *
  8644. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8645. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8646. + *
  8647. + * This file was derived from: include/asm-mips/cpu-features.h
  8648. + * Copyright (C) 2003, 2004 Ralf Baechle
  8649. + * Copyright (C) 2004 Maciej W. Rozycki
  8650. + *
  8651. + * This program is free software; you can redistribute it and/or modify it
  8652. + * under the terms of the GNU General Public License version 2 as published
  8653. + * by the Free Software Foundation.
  8654. + *
  8655. + */
  8656. +#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8657. +#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H
  8658. +
  8659. +#define cpu_has_tlb 1
  8660. +#define cpu_has_4kex 1
  8661. +#define cpu_has_3k_cache 0
  8662. +#define cpu_has_4k_cache 1
  8663. +#define cpu_has_tx39_cache 0
  8664. +#define cpu_has_sb1_cache 0
  8665. +#define cpu_has_fpu 0
  8666. +#define cpu_has_32fpr 0
  8667. +#define cpu_has_counter 1
  8668. +#define cpu_has_watch 1
  8669. +#define cpu_has_divec 1
  8670. +
  8671. +#define cpu_has_prefetch 1
  8672. +#define cpu_has_ejtag 1
  8673. +#define cpu_has_llsc 1
  8674. +
  8675. +#define cpu_has_mips16 1
  8676. +#define cpu_has_mdmx 0
  8677. +#define cpu_has_mips3d 0
  8678. +#define cpu_has_smartmips 0
  8679. +
  8680. +#define cpu_has_mips32r1 1
  8681. +#define cpu_has_mips32r2 1
  8682. +#define cpu_has_mips64r1 0
  8683. +#define cpu_has_mips64r2 0
  8684. +
  8685. +#define cpu_has_dsp 0
  8686. +#define cpu_has_mipsmt 0
  8687. +
  8688. +#define cpu_has_64bits 0
  8689. +#define cpu_has_64bit_zero_reg 0
  8690. +#define cpu_has_64bit_gp_regs 0
  8691. +#define cpu_has_64bit_addresses 0
  8692. +
  8693. +#define cpu_dcache_line_size() 32
  8694. +#define cpu_icache_line_size() 32
  8695. +
  8696. +#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */
  8697. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/gpio.h
  8698. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100
  8699. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-01-11 20:25:48.000000000 +0100
  8700. @@ -0,0 +1,53 @@
  8701. +/*
  8702. + * Atheros AR71xx GPIO API definitions
  8703. + *
  8704. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8705. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8706. + *
  8707. + * This program is free software; you can redistribute it and/or modify it
  8708. + * under the terms of the GNU General Public License version 2 as published
  8709. + * by the Free Software Foundation.
  8710. + *
  8711. + */
  8712. +
  8713. +#ifndef __ASM_MACH_AR71XX_GPIO_H
  8714. +#define __ASM_MACH_AR71XX_GPIO_H
  8715. +
  8716. +#define ARCH_NR_GPIOS 64
  8717. +#include <asm-generic/gpio.h>
  8718. +
  8719. +#include <asm/mach-ar71xx/ar71xx.h>
  8720. +
  8721. +extern unsigned long ar71xx_gpio_count;
  8722. +extern void __ar71xx_gpio_set_value(unsigned gpio, int value);
  8723. +extern int __ar71xx_gpio_get_value(unsigned gpio);
  8724. +
  8725. +static inline int gpio_to_irq(unsigned gpio)
  8726. +{
  8727. + return AR71XX_GPIO_IRQ(gpio);
  8728. +}
  8729. +
  8730. +static inline int irq_to_gpio(unsigned irq)
  8731. +{
  8732. + return irq - AR71XX_GPIO_IRQ_BASE;
  8733. +}
  8734. +
  8735. +static inline int gpio_get_value(unsigned gpio)
  8736. +{
  8737. + if (gpio < ar71xx_gpio_count)
  8738. + return __ar71xx_gpio_get_value(gpio);
  8739. +
  8740. + return __gpio_get_value(gpio);
  8741. +}
  8742. +
  8743. +static inline void gpio_set_value(unsigned gpio, int value)
  8744. +{
  8745. + if (gpio < ar71xx_gpio_count)
  8746. + __ar71xx_gpio_set_value(gpio, value);
  8747. + else
  8748. + __gpio_set_value(gpio, value);
  8749. +}
  8750. +
  8751. +#define gpio_cansleep __gpio_cansleep
  8752. +
  8753. +#endif /* __ASM_MACH_AR71XX_GPIO_H */
  8754. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/irq.h
  8755. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100
  8756. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/irq.h 2011-01-11 20:25:48.000000000 +0100
  8757. @@ -0,0 +1,17 @@
  8758. +/*
  8759. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8760. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8761. + *
  8762. + * This program is free software; you can redistribute it and/or modify it
  8763. + * under the terms of the GNU General Public License version 2 as published
  8764. + * by the Free Software Foundation.
  8765. + */
  8766. +#ifndef __ASM_MACH_AR71XX_IRQ_H
  8767. +#define __ASM_MACH_AR71XX_IRQ_H
  8768. +
  8769. +#define MIPS_CPU_IRQ_BASE 0
  8770. +#define NR_IRQS 56
  8771. +
  8772. +#include_next <irq.h>
  8773. +
  8774. +#endif /* __ASM_MACH_AR71XX_IRQ_H */
  8775. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h
  8776. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100
  8777. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-01-11 20:25:48.000000000 +0100
  8778. @@ -0,0 +1,32 @@
  8779. +/*
  8780. + * Atheros AR71xx specific kernel entry setup
  8781. + *
  8782. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  8783. + *
  8784. + * This program is free software; you can redistribute it and/or modify it
  8785. + * under the terms of the GNU General Public License version 2 as published
  8786. + * by the Free Software Foundation.
  8787. + *
  8788. + */
  8789. +#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8790. +#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H
  8791. +
  8792. + /*
  8793. + * Some bootloaders set the 'Kseg0 coherency algorithm' to
  8794. + * 'Cacheable, noncoherent, write-through, no write allocate'
  8795. + * and this cause performance issues. Let's go and change it to
  8796. + * 'Cacheable, noncoherent, write-back, write allocate'
  8797. + */
  8798. + .macro kernel_entry_setup
  8799. + mfc0 t0, CP0_CONFIG
  8800. + li t1, ~CONF_CM_CMASK
  8801. + and t0, t1
  8802. + ori t0, CONF_CM_CACHABLE_NONCOHERENT
  8803. + mtc0 t0, CP0_CONFIG
  8804. + nop
  8805. + .endm
  8806. +
  8807. + .macro smp_slave_setup
  8808. + .endm
  8809. +
  8810. +#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */
  8811. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/mach-rb750.h
  8812. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100
  8813. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-01-11 20:25:48.000000000 +0100
  8814. @@ -0,0 +1,66 @@
  8815. +/*
  8816. + * MikroTik RouterBOARD 750 definitions
  8817. + *
  8818. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  8819. + *
  8820. + * This program is free software; you can redistribute it and/or modify it
  8821. + * under the terms of the GNU General Public License version 2 as published
  8822. + * by the Free Software Foundation.
  8823. + */
  8824. +#ifndef _MACH_RB750_H
  8825. +#define _MACH_RB750_H
  8826. +
  8827. +#include <linux/bitops.h>
  8828. +
  8829. +#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */
  8830. +#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */
  8831. +#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */
  8832. +#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */
  8833. +#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */
  8834. +#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */
  8835. +#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */
  8836. +#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */
  8837. +#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */
  8838. +#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */
  8839. +#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */
  8840. +#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */
  8841. +#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */
  8842. +#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */
  8843. +#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */
  8844. +
  8845. +#define RB750_GPIO_BTN_RESET 1
  8846. +#define RB750_GPIO_SPI_CS0 2
  8847. +#define RB750_GPIO_LED_ACT 12
  8848. +#define RB750_GPIO_LED_PORT1 13
  8849. +#define RB750_GPIO_LED_PORT2 14
  8850. +#define RB750_GPIO_LED_PORT3 15
  8851. +#define RB750_GPIO_LED_PORT4 16
  8852. +#define RB750_GPIO_LED_PORT5 17
  8853. +
  8854. +#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT)
  8855. +#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1)
  8856. +#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2)
  8857. +#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3)
  8858. +#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4)
  8859. +#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5)
  8860. +
  8861. +#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE)
  8862. +
  8863. +#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \
  8864. + RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT)
  8865. +
  8866. +struct rb750_led_data {
  8867. + char *name;
  8868. + char *default_trigger;
  8869. + u32 mask;
  8870. + int active_low;
  8871. +};
  8872. +
  8873. +struct rb750_led_platform_data {
  8874. + int num_leds;
  8875. + struct rb750_led_data *leds;
  8876. +};
  8877. +
  8878. +int rb750_latch_change(u32 mask_clr, u32 mask_set);
  8879. +
  8880. +#endif /* _MACH_RB750_H */
  8881. \ No newline at end of file
  8882. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/mangle-port.h
  8883. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100
  8884. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-01-11 20:25:48.000000000 +0100
  8885. @@ -0,0 +1,45 @@
  8886. +/*
  8887. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  8888. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8889. + *
  8890. + * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
  8891. + * Copyright (C) 2003, 2004 Ralf Baechle
  8892. + *
  8893. + * This program is free software; you can redistribute it and/or modify it
  8894. + * under the terms of the GNU General Public License version 2 as published
  8895. + * by the Free Software Foundation.
  8896. + */
  8897. +
  8898. +#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H
  8899. +#define __ASM_MACH_AR71XX_MANGLE_PORT_H
  8900. +
  8901. +#define __swizzle_addr_b(port) ((port) ^ 3)
  8902. +#define __swizzle_addr_w(port) ((port) ^ 2)
  8903. +#define __swizzle_addr_l(port) (port)
  8904. +#define __swizzle_addr_q(port) (port)
  8905. +
  8906. +#if defined(CONFIG_SWAP_IO_SPACE)
  8907. +
  8908. +# define ioswabb(a, x) (x)
  8909. +# define __mem_ioswabb(a, x) (x)
  8910. +# define ioswabw(a, x) le16_to_cpu(x)
  8911. +# define __mem_ioswabw(a, x) (x)
  8912. +# define ioswabl(a, x) le32_to_cpu(x)
  8913. +# define __mem_ioswabl(a, x) (x)
  8914. +# define ioswabq(a, x) le64_to_cpu(x)
  8915. +# define __mem_ioswabq(a, x) (x)
  8916. +
  8917. +#else
  8918. +
  8919. +# define ioswabb(a, x) (x)
  8920. +# define __mem_ioswabb(a, x) (x)
  8921. +# define ioswabw(a, x) (x)
  8922. +# define __mem_ioswabw(a, x) cpu_to_le16(x)
  8923. +# define ioswabl(a, x) (x)
  8924. +# define __mem_ioswabl(a, x) cpu_to_le32(x)
  8925. +# define ioswabq(a, x) (x)
  8926. +# define __mem_ioswabq(a, x) cpu_to_le64(x)
  8927. +
  8928. +#endif
  8929. +
  8930. +#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */
  8931. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/pci.h
  8932. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100
  8933. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/pci.h 2011-01-11 20:25:48.000000000 +0100
  8934. @@ -0,0 +1,39 @@
  8935. +/*
  8936. + * Atheros AR71xx SoC specific PCI definitions
  8937. + *
  8938. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8939. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8940. + *
  8941. + * This program is free software; you can redistribute it and/or modify it
  8942. + * under the terms of the GNU General Public License version 2 as published
  8943. + * by the Free Software Foundation.
  8944. + */
  8945. +
  8946. +#ifndef __ASM_MACH_AR71XX_PCI_H
  8947. +#define __ASM_MACH_AR71XX_PCI_H
  8948. +
  8949. +struct pci_dev;
  8950. +
  8951. +struct ar71xx_pci_irq {
  8952. + int irq;
  8953. + u8 slot;
  8954. + u8 pin;
  8955. +};
  8956. +
  8957. +extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
  8958. +extern unsigned ar71xx_pci_nr_irqs __initdata;
  8959. +extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
  8960. +
  8961. +int ar71xx_pcibios_map_irq(const struct pci_dev *dev,
  8962. + uint8_t slot, uint8_t pin) __init;
  8963. +int ar71xx_pcibios_init(void) __init;
  8964. +
  8965. +int ar71xx_pci_be_handler(int is_fixup);
  8966. +
  8967. +int ar724x_pcibios_map_irq(const struct pci_dev *dev,
  8968. + uint8_t slot, uint8_t pin) __init;
  8969. +int ar724x_pcibios_init(void) __init;
  8970. +
  8971. +int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init;
  8972. +
  8973. +#endif /* __ASM_MACH_AR71XX_PCI_H */
  8974. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/platform.h
  8975. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100
  8976. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/platform.h 2011-01-11 20:25:48.000000000 +0100
  8977. @@ -0,0 +1,61 @@
  8978. +/*
  8979. + * Atheros AR71xx SoC specific platform data definitions
  8980. + *
  8981. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  8982. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  8983. + *
  8984. + * This program is free software; you can redistribute it and/or modify it
  8985. + * under the terms of the GNU General Public License version 2 as published
  8986. + * by the Free Software Foundation.
  8987. + */
  8988. +
  8989. +#ifndef __ASM_MACH_AR71XX_PLATFORM_H
  8990. +#define __ASM_MACH_AR71XX_PLATFORM_H
  8991. +
  8992. +#include <linux/if_ether.h>
  8993. +#include <linux/skbuff.h>
  8994. +#include <linux/phy.h>
  8995. +#include <linux/spi/spi.h>
  8996. +
  8997. +struct ag71xx_platform_data {
  8998. + phy_interface_t phy_if_mode;
  8999. + u32 phy_mask;
  9000. + int speed;
  9001. + int duplex;
  9002. + u32 reset_bit;
  9003. + u32 mii_if;
  9004. + u8 mac_addr[ETH_ALEN];
  9005. + struct device *mii_bus_dev;
  9006. +
  9007. + u8 has_gbit:1;
  9008. + u8 is_ar91xx:1;
  9009. + u8 is_ar724x:1;
  9010. + u8 has_ar8216:1;
  9011. +
  9012. + void (* ddr_flush)(void);
  9013. + void (* set_pll)(int speed);
  9014. +
  9015. + u32 fifo_cfg1;
  9016. + u32 fifo_cfg2;
  9017. + u32 fifo_cfg3;
  9018. +};
  9019. +
  9020. +struct ag71xx_mdio_platform_data {
  9021. + u32 phy_mask;
  9022. + int is_ar7240;
  9023. +};
  9024. +
  9025. +struct ar71xx_ehci_platform_data {
  9026. + u8 is_ar91xx;
  9027. +};
  9028. +
  9029. +struct ar71xx_spi_platform_data {
  9030. + unsigned bus_num;
  9031. + unsigned num_chipselect;
  9032. + u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on);
  9033. +};
  9034. +
  9035. +#define AR71XX_SPI_CS_INACTIVE 0
  9036. +#define AR71XX_SPI_CS_ACTIVE 1
  9037. +
  9038. +#endif /* __ASM_MACH_AR71XX_PLATFORM_H */
  9039. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.37/arch/mips/include/asm/mach-ar71xx/war.h
  9040. --- linux-2.6.37.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100
  9041. +++ linux-2.6.37/arch/mips/include/asm/mach-ar71xx/war.h 2011-01-11 20:25:48.000000000 +0100
  9042. @@ -0,0 +1,25 @@
  9043. +/*
  9044. + * This file is subject to the terms and conditions of the GNU General Public
  9045. + * License. See the file "COPYING" in the main directory of this archive
  9046. + * for more details.
  9047. + *
  9048. + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  9049. + */
  9050. +#ifndef __ASM_MACH_AR71XX_WAR_H
  9051. +#define __ASM_MACH_AR71XX_WAR_H
  9052. +
  9053. +#define R4600_V1_INDEX_ICACHEOP_WAR 0
  9054. +#define R4600_V1_HIT_CACHEOP_WAR 0
  9055. +#define R4600_V2_HIT_CACHEOP_WAR 0
  9056. +#define R5432_CP0_INTERRUPT_WAR 0
  9057. +#define BCM1250_M3_WAR 0
  9058. +#define SIBYTE_1956_WAR 0
  9059. +#define MIPS4K_ICACHE_REFILL_WAR 0
  9060. +#define MIPS_CACHE_SYNC_WAR 0
  9061. +#define TX49XX_ICACHE_INDEX_INV_WAR 0
  9062. +#define RM9000_CDEX_SMP_WAR 0
  9063. +#define ICACHE_REFILLS_WORKAROUND_WAR 0
  9064. +#define R10000_LLSC_WAR 0
  9065. +#define MIPS34K_MISSED_ITLB_WAR 0
  9066. +
  9067. +#endif /* __ASM_MACH_AR71XX_WAR_H */
  9068. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mips_machine.h linux-2.6.37/arch/mips/include/asm/mips_machine.h
  9069. --- linux-2.6.37.orig/arch/mips/include/asm/mips_machine.h 1970-01-01 01:00:00.000000000 +0100
  9070. +++ linux-2.6.37/arch/mips/include/asm/mips_machine.h 2011-01-11 20:25:48.000000000 +0100
  9071. @@ -0,0 +1,54 @@
  9072. +/*
  9073. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  9074. + *
  9075. + * This program is free software; you can redistribute it and/or modify it
  9076. + * under the terms of the GNU General Public License version 2 as published
  9077. + * by the Free Software Foundation.
  9078. + *
  9079. + */
  9080. +
  9081. +#ifndef __ASM_MIPS_MACHINE_H
  9082. +#define __ASM_MIPS_MACHINE_H
  9083. +
  9084. +#include <linux/init.h>
  9085. +#include <linux/list.h>
  9086. +
  9087. +#include <asm/bootinfo.h>
  9088. +
  9089. +struct mips_machine {
  9090. + unsigned long mach_type;
  9091. + char *mach_id;
  9092. + char *mach_name;
  9093. + void (*mach_setup)(void);
  9094. + struct list_head list;
  9095. +};
  9096. +
  9097. +void mips_machine_register(struct mips_machine *) __init;
  9098. +void mips_machine_setup(void) __init;
  9099. +int mips_machtype_setup(char *id) __init;
  9100. +void mips_machine_set_name(char *name) __init;
  9101. +
  9102. +extern char *mips_machine_name;
  9103. +
  9104. +#define MIPS_MACHINE(_type, _id, _name, _setup) \
  9105. +static const char machine_name_##_type[] __initconst \
  9106. + __aligned(1) = _name; \
  9107. +static const char machine_id_##_type[] __initconst \
  9108. + __aligned(1) = _id; \
  9109. +static struct mips_machine machine_##_type __initdata = \
  9110. +{ \
  9111. + .mach_type = _type, \
  9112. + .mach_id = (char *) machine_id_##_type, \
  9113. + .mach_name = (char *) machine_name_##_type, \
  9114. + .mach_setup = _setup, \
  9115. +}; \
  9116. + \
  9117. +static int __init register_machine_##_type(void) \
  9118. +{ \
  9119. + mips_machine_register(&machine_##_type); \
  9120. + return 0; \
  9121. +} \
  9122. + \
  9123. +pure_initcall(register_machine_##_type)
  9124. +
  9125. +#endif /* __ASM_MIPS_MACHINE_H */
  9126. diff -Nur linux-2.6.37.orig/arch/mips/include/asm/time.h linux-2.6.37/arch/mips/include/asm/time.h
  9127. --- linux-2.6.37.orig/arch/mips/include/asm/time.h 2011-01-05 01:50:19.000000000 +0100
  9128. +++ linux-2.6.37/arch/mips/include/asm/time.h 2011-01-11 20:25:48.000000000 +0100
  9129. @@ -52,6 +52,7 @@
  9130. */
  9131. #ifdef CONFIG_CEVT_R4K_LIB
  9132. extern unsigned int __weak get_c0_compare_int(void);
  9133. +extern unsigned int __weak get_c0_compare_irq(void);
  9134. extern int r4k_clockevent_init(void);
  9135. #endif
  9136. diff -Nur linux-2.6.37.orig/arch/mips/kernel/Makefile linux-2.6.37/arch/mips/kernel/Makefile
  9137. --- linux-2.6.37.orig/arch/mips/kernel/Makefile 2011-01-05 01:50:19.000000000 +0100
  9138. +++ linux-2.6.37/arch/mips/kernel/Makefile 2011-01-11 20:25:48.000000000 +0100
  9139. @@ -94,6 +94,7 @@
  9140. obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
  9141. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  9142. +obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
  9143. obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
  9144. obj-$(CONFIG_OF) += prom.o
  9145. diff -Nur linux-2.6.37.orig/arch/mips/kernel/mips_machine.c linux-2.6.37/arch/mips/kernel/mips_machine.c
  9146. --- linux-2.6.37.orig/arch/mips/kernel/mips_machine.c 1970-01-01 01:00:00.000000000 +0100
  9147. +++ linux-2.6.37/arch/mips/kernel/mips_machine.c 2011-01-11 20:25:48.000000000 +0100
  9148. @@ -0,0 +1,121 @@
  9149. +/*
  9150. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  9151. + *
  9152. + * This program is free software; you can redistribute it and/or modify it
  9153. + * under the terms of the GNU General Public License version 2 as published
  9154. + * by the Free Software Foundation.
  9155. + *
  9156. + */
  9157. +#include <linux/mm.h>
  9158. +#include <linux/slab.h>
  9159. +#include <linux/string.h>
  9160. +
  9161. +#include <asm/mips_machine.h>
  9162. +
  9163. +static struct list_head mips_machines __initdata =
  9164. + LIST_HEAD_INIT(mips_machines);
  9165. +static char *mips_machid __initdata;
  9166. +
  9167. +char *mips_machine_name = "Unknown";
  9168. +
  9169. +static struct mips_machine * __init mips_machine_find(unsigned long machtype)
  9170. +{
  9171. + struct list_head *this;
  9172. +
  9173. + list_for_each(this, &mips_machines) {
  9174. + struct mips_machine *mach;
  9175. +
  9176. + mach = list_entry(this, struct mips_machine, list);
  9177. + if (mach->mach_type == machtype)
  9178. + return mach;
  9179. + }
  9180. +
  9181. + return NULL;
  9182. +}
  9183. +
  9184. +void __init mips_machine_register(struct mips_machine *mach)
  9185. +{
  9186. + list_add_tail(&mach->list, &mips_machines);
  9187. +}
  9188. +
  9189. +void __init mips_machine_set_name(char *name)
  9190. +{
  9191. + unsigned int len;
  9192. + char *p;
  9193. +
  9194. + if (name == NULL)
  9195. + return;
  9196. +
  9197. + len = strlen(name);
  9198. + p = kmalloc(len + 1, GFP_KERNEL);
  9199. + if (p) {
  9200. + strncpy(p, name, len);
  9201. + p[len] = '\0';
  9202. + mips_machine_name = p;
  9203. + } else {
  9204. + printk(KERN_WARNING "MIPS: no memory for machine_name\n");
  9205. + }
  9206. +}
  9207. +
  9208. +void __init mips_machine_setup(void)
  9209. +{
  9210. + struct mips_machine *mach;
  9211. +
  9212. + mach = mips_machine_find(mips_machtype);
  9213. + if (!mach) {
  9214. + printk(KERN_WARNING "MIPS: no machine registered for "
  9215. + "machtype %lu\n", mips_machtype);
  9216. + return;
  9217. + }
  9218. +
  9219. + mips_machine_set_name(mach->mach_name);
  9220. + printk(KERN_NOTICE "MIPS: machine is %s\n", mips_machine_name);
  9221. +
  9222. + if (mach->mach_setup)
  9223. + mach->mach_setup();
  9224. +}
  9225. +
  9226. +int __init mips_machtype_setup(char *id)
  9227. +{
  9228. + if (mips_machid == NULL)
  9229. + mips_machid = id;
  9230. +
  9231. + return 1;
  9232. +}
  9233. +
  9234. +__setup("machtype=", mips_machtype_setup);
  9235. +
  9236. +static int __init mips_machtype_init(void)
  9237. +{
  9238. + struct list_head *this;
  9239. + struct mips_machine *mach;
  9240. +
  9241. + if (mips_machid == NULL)
  9242. + return 0;
  9243. +
  9244. + list_for_each(this, &mips_machines) {
  9245. + mach = list_entry(this, struct mips_machine, list);
  9246. + if (mach->mach_id == NULL)
  9247. + continue;
  9248. +
  9249. + if (strcmp(mach->mach_id, mips_machid) == 0) {
  9250. + mips_machtype = mach->mach_type;
  9251. + return 0;
  9252. + }
  9253. + }
  9254. +
  9255. + printk(KERN_WARNING
  9256. + "MIPS: no machine found for id: '%s', registered machines:\n",
  9257. + mips_machid);
  9258. + printk(KERN_WARNING "%32s %s\n", "id", "name");
  9259. +
  9260. + list_for_each(this, &mips_machines) {
  9261. + mach = list_entry(this, struct mips_machine, list);
  9262. + printk(KERN_WARNING "%32s %s\n",
  9263. + mach->mach_id ? mach->mach_id : "", mach->mach_name);
  9264. + }
  9265. +
  9266. + return 0;
  9267. +}
  9268. +
  9269. +core_initcall(mips_machtype_init);
  9270. diff -Nur linux-2.6.37.orig/arch/mips/kernel/proc.c linux-2.6.37/arch/mips/kernel/proc.c
  9271. --- linux-2.6.37.orig/arch/mips/kernel/proc.c 2011-01-05 01:50:19.000000000 +0100
  9272. +++ linux-2.6.37/arch/mips/kernel/proc.c 2011-01-11 20:25:48.000000000 +0100
  9273. @@ -12,6 +12,7 @@
  9274. #include <asm/cpu-features.h>
  9275. #include <asm/mipsregs.h>
  9276. #include <asm/processor.h>
  9277. +#include <asm/mips_machine.h>
  9278. unsigned int vced_count, vcei_count;
  9279. @@ -31,8 +32,12 @@
  9280. /*
  9281. * For the first processor also print the system type
  9282. */
  9283. - if (n == 0)
  9284. + if (n == 0) {
  9285. seq_printf(m, "system type\t\t: %s\n", get_system_type());
  9286. +#ifdef CONFIG_MIPS_MACHINE
  9287. + seq_printf(m, "machine\t\t\t: %s\n", mips_machine_name);
  9288. +#endif
  9289. + }
  9290. seq_printf(m, "processor\t\t: %ld\n", n);
  9291. sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
  9292. diff -Nur linux-2.6.37.orig/arch/mips/kernel/traps.c linux-2.6.37/arch/mips/kernel/traps.c
  9293. --- linux-2.6.37.orig/arch/mips/kernel/traps.c 2011-01-05 01:50:19.000000000 +0100
  9294. +++ linux-2.6.37/arch/mips/kernel/traps.c 2011-01-11 20:26:51.000000000 +0100
  9295. @@ -46,6 +46,7 @@
  9296. #include <asm/ptrace.h>
  9297. #include <asm/sections.h>
  9298. #include <asm/system.h>
  9299. +#include <asm/time.h>
  9300. #include <asm/tlbdebug.h>
  9301. #include <asm/traps.h>
  9302. #include <asm/uaccess.h>
  9303. @@ -1578,6 +1579,8 @@
  9304. if (cpu_has_mips_r2) {
  9305. cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
  9306. cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
  9307. + if (get_c0_compare_irq)
  9308. + cp0_compare_irq = get_c0_compare_irq();
  9309. cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
  9310. if (cp0_perfcount_irq == cp0_compare_irq)
  9311. cp0_perfcount_irq = -1;
  9312. diff -Nur linux-2.6.37.orig/arch/mips/pci/Makefile linux-2.6.37/arch/mips/pci/Makefile
  9313. --- linux-2.6.37.orig/arch/mips/pci/Makefile 2011-01-05 01:50:19.000000000 +0100
  9314. +++ linux-2.6.37/arch/mips/pci/Makefile 2011-01-11 20:25:48.000000000 +0100
  9315. @@ -18,6 +18,7 @@
  9316. obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
  9317. obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
  9318. ops-bcm63xx.o
  9319. +obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o
  9320. #
  9321. # These are still pretty much in the old state, watch, go blind.
  9322. diff -Nur linux-2.6.37.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.37/arch/mips/pci/pci-ar71xx.c
  9323. --- linux-2.6.37.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  9324. +++ linux-2.6.37/arch/mips/pci/pci-ar71xx.c 2011-01-11 20:25:48.000000000 +0100
  9325. @@ -0,0 +1,409 @@
  9326. +/*
  9327. + * Atheros AR71xx PCI host controller driver
  9328. + *
  9329. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  9330. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  9331. + *
  9332. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9333. + *
  9334. + * This program is free software; you can redistribute it and/or modify it
  9335. + * under the terms of the GNU General Public License version 2 as published
  9336. + * by the Free Software Foundation.
  9337. + */
  9338. +
  9339. +#include <linux/resource.h>
  9340. +#include <linux/types.h>
  9341. +#include <linux/delay.h>
  9342. +#include <linux/bitops.h>
  9343. +#include <linux/pci.h>
  9344. +#include <linux/pci_regs.h>
  9345. +#include <linux/interrupt.h>
  9346. +
  9347. +#include <asm/mach-ar71xx/ar71xx.h>
  9348. +#include <asm/mach-ar71xx/pci.h>
  9349. +
  9350. +#undef DEBUG
  9351. +#ifdef DEBUG
  9352. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  9353. +#else
  9354. +#define DBG(fmt, args...)
  9355. +#endif
  9356. +
  9357. +#define AR71XX_PCI_DELAY 100 /* msecs */
  9358. +
  9359. +#if 0
  9360. +#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START
  9361. +#else
  9362. +#define PCI_IDSEL_BASE 0
  9363. +#endif
  9364. +
  9365. +static void __iomem *ar71xx_pcicfg_base;
  9366. +static DEFINE_SPINLOCK(ar71xx_pci_lock);
  9367. +static int ar71xx_pci_fixup_enable;
  9368. +
  9369. +static inline void ar71xx_pci_delay(void)
  9370. +{
  9371. + mdelay(AR71XX_PCI_DELAY);
  9372. +}
  9373. +
  9374. +/* Byte lane enable bits */
  9375. +static u8 ble_table[4][4] = {
  9376. + {0x0, 0xf, 0xf, 0xf},
  9377. + {0xe, 0xd, 0xb, 0x7},
  9378. + {0xc, 0xf, 0x3, 0xf},
  9379. + {0xf, 0xf, 0xf, 0xf},
  9380. +};
  9381. +
  9382. +static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
  9383. +{
  9384. + u32 t;
  9385. +
  9386. + t = ble_table[size & 3][where & 3];
  9387. + BUG_ON(t == 0xf);
  9388. + t <<= (local) ? 20 : 4;
  9389. + return t;
  9390. +}
  9391. +
  9392. +static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
  9393. + int where)
  9394. +{
  9395. + u32 ret;
  9396. +
  9397. + if (!bus->number) {
  9398. + /* type 0 */
  9399. + ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn)))
  9400. + | (PCI_FUNC(devfn) << 8) | (where & ~3);
  9401. + } else {
  9402. + /* type 1 */
  9403. + ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11)
  9404. + | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
  9405. + }
  9406. +
  9407. + return ret;
  9408. +}
  9409. +
  9410. +int ar71xx_pci_be_handler(int is_fixup)
  9411. +{
  9412. + void __iomem *base = ar71xx_pcicfg_base;
  9413. + u32 pci_err;
  9414. + u32 ahb_err;
  9415. +
  9416. + pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3;
  9417. + if (pci_err) {
  9418. + if (!is_fixup)
  9419. + printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n",
  9420. + pci_err,
  9421. + __raw_readl(base + PCI_REG_PCI_ERR_ADDR));
  9422. +
  9423. + __raw_writel(pci_err, base + PCI_REG_PCI_ERR);
  9424. + }
  9425. +
  9426. + ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1;
  9427. + if (ahb_err) {
  9428. + if (!is_fixup)
  9429. + printk(KERN_ALERT "AHB error at AHB address 0x%x\n",
  9430. + __raw_readl(base + PCI_REG_AHB_ERR_ADDR));
  9431. +
  9432. + __raw_writel(ahb_err, base + PCI_REG_AHB_ERR);
  9433. + }
  9434. +
  9435. + return ((ahb_err | pci_err) ? 1 : 0);
  9436. +}
  9437. +
  9438. +static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
  9439. + unsigned int devfn, int where, int size, u32 cmd)
  9440. +{
  9441. + void __iomem *base = ar71xx_pcicfg_base;
  9442. + u32 addr;
  9443. +
  9444. + addr = ar71xx_pci_bus_addr(bus, devfn, where);
  9445. +
  9446. + DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n",
  9447. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9448. + where, size, addr);
  9449. +
  9450. + __raw_writel(addr, base + PCI_REG_CFG_AD);
  9451. + __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
  9452. + base + PCI_REG_CFG_CBE);
  9453. +
  9454. + return ar71xx_pci_be_handler(1);
  9455. +}
  9456. +
  9457. +static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9458. + int where, int size, u32 *value)
  9459. +{
  9460. + void __iomem *base = ar71xx_pcicfg_base;
  9461. + static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
  9462. + unsigned long flags;
  9463. + u32 data;
  9464. + int ret;
  9465. +
  9466. + ret = PCIBIOS_SUCCESSFUL;
  9467. +
  9468. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number,
  9469. + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
  9470. +
  9471. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9472. +
  9473. + if (bus->number == 0 && devfn == 0) {
  9474. + u32 t;
  9475. +
  9476. + t = PCI_CRP_CMD_READ | (where & ~3);
  9477. +
  9478. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9479. + data = __raw_readl(base + PCI_REG_CRP_RDDATA);
  9480. +
  9481. + DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data);
  9482. +
  9483. + } else {
  9484. + int err;
  9485. +
  9486. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9487. + PCI_CFG_CMD_READ);
  9488. +
  9489. + if (err == 0) {
  9490. + data = __raw_readl(base + PCI_REG_CFG_RDDATA);
  9491. + } else {
  9492. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9493. + data = ~0;
  9494. + }
  9495. + }
  9496. +
  9497. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9498. +
  9499. + DBG("PCI: read config: data=%08x raw=%08x\n",
  9500. + (data >> (8 * (where & 3))) & mask[size & 7], data);
  9501. +
  9502. + *value = (data >> (8 * (where & 3))) & mask[size & 7];
  9503. +
  9504. + return ret;
  9505. +}
  9506. +
  9507. +static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9508. + int where, int size, u32 value)
  9509. +{
  9510. + void __iomem *base = ar71xx_pcicfg_base;
  9511. + unsigned long flags;
  9512. + int ret;
  9513. +
  9514. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n",
  9515. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9516. + where, size, value);
  9517. +
  9518. + value = value << (8 * (where & 3));
  9519. + ret = PCIBIOS_SUCCESSFUL;
  9520. +
  9521. + spin_lock_irqsave(&ar71xx_pci_lock, flags);
  9522. + if (bus->number == 0 && devfn == 0) {
  9523. + u32 t;
  9524. +
  9525. + t = PCI_CRP_CMD_WRITE | (where & ~3);
  9526. + t |= ar71xx_pci_get_ble(where, size, 1);
  9527. +
  9528. + DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value);
  9529. +
  9530. + __raw_writel(t, base + PCI_REG_CRP_AD_CBE);
  9531. + __raw_writel(value, base + PCI_REG_CRP_WRDATA);
  9532. + } else {
  9533. + int err;
  9534. +
  9535. + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
  9536. + PCI_CFG_CMD_WRITE);
  9537. +
  9538. + if (err == 0)
  9539. + __raw_writel(value, base + PCI_REG_CFG_WRDATA);
  9540. + else
  9541. + ret = PCIBIOS_DEVICE_NOT_FOUND;
  9542. + }
  9543. + spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
  9544. +
  9545. + return ret;
  9546. +}
  9547. +
  9548. +static void ar71xx_pci_fixup(struct pci_dev *dev)
  9549. +{
  9550. + u32 t;
  9551. +
  9552. + if (!ar71xx_pci_fixup_enable)
  9553. + return;
  9554. +
  9555. + if (dev->bus->number != 0 || dev->devfn != 0)
  9556. + return;
  9557. +
  9558. + DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev),
  9559. + dev->vendor, dev->device);
  9560. +
  9561. + /* setup COMMAND register */
  9562. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
  9563. + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
  9564. +
  9565. + pci_write_config_word(dev, PCI_COMMAND, t);
  9566. +}
  9567. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup);
  9568. +
  9569. +int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9570. + uint8_t pin)
  9571. +{
  9572. + int irq = -1;
  9573. + int i;
  9574. +
  9575. + slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE;
  9576. +
  9577. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9578. + struct ar71xx_pci_irq *entry;
  9579. +
  9580. + entry = &ar71xx_pci_irq_map[i];
  9581. + if (entry->slot == slot && entry->pin == pin) {
  9582. + irq = entry->irq;
  9583. + break;
  9584. + }
  9585. + }
  9586. +
  9587. + if (irq < 0) {
  9588. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9589. + pin, pci_name((struct pci_dev *)dev));
  9590. + } else {
  9591. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9592. + irq, pin, pci_name((struct pci_dev *)dev));
  9593. + }
  9594. +
  9595. + return irq;
  9596. +}
  9597. +
  9598. +static struct pci_ops ar71xx_pci_ops = {
  9599. + .read = ar71xx_pci_read_config,
  9600. + .write = ar71xx_pci_write_config,
  9601. +};
  9602. +
  9603. +static struct resource ar71xx_pci_io_resource = {
  9604. + .name = "PCI IO space",
  9605. + .start = 0,
  9606. + .end = 0,
  9607. + .flags = IORESOURCE_IO,
  9608. +};
  9609. +
  9610. +static struct resource ar71xx_pci_mem_resource = {
  9611. + .name = "PCI memory space",
  9612. + .start = AR71XX_PCI_MEM_BASE,
  9613. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9614. + .flags = IORESOURCE_MEM
  9615. +};
  9616. +
  9617. +static struct pci_controller ar71xx_pci_controller = {
  9618. + .pci_ops = &ar71xx_pci_ops,
  9619. + .mem_resource = &ar71xx_pci_mem_resource,
  9620. + .io_resource = &ar71xx_pci_io_resource,
  9621. +};
  9622. +
  9623. +static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  9624. +{
  9625. + void __iomem *base = ar71xx_reset_base;
  9626. + u32 pending;
  9627. +
  9628. + pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
  9629. + __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9630. +
  9631. + if (pending & PCI_INT_DEV0)
  9632. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  9633. +
  9634. + else if (pending & PCI_INT_DEV1)
  9635. + generic_handle_irq(AR71XX_PCI_IRQ_DEV1);
  9636. +
  9637. + else if (pending & PCI_INT_DEV2)
  9638. + generic_handle_irq(AR71XX_PCI_IRQ_DEV2);
  9639. +
  9640. + else if (pending & PCI_INT_CORE)
  9641. + generic_handle_irq(AR71XX_PCI_IRQ_CORE);
  9642. +
  9643. + else
  9644. + spurious_interrupt();
  9645. +}
  9646. +
  9647. +static void ar71xx_pci_irq_unmask(unsigned int irq)
  9648. +{
  9649. + void __iomem *base = ar71xx_reset_base;
  9650. + u32 t;
  9651. +
  9652. + irq -= AR71XX_PCI_IRQ_BASE;
  9653. +
  9654. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9655. + __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9656. +
  9657. + /* flush write */
  9658. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9659. +}
  9660. +
  9661. +static void ar71xx_pci_irq_mask(unsigned int irq)
  9662. +{
  9663. + void __iomem *base = ar71xx_reset_base;
  9664. + u32 t;
  9665. +
  9666. + irq -= AR71XX_PCI_IRQ_BASE;
  9667. +
  9668. + t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9669. + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9670. +
  9671. + /* flush write */
  9672. + (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9673. +}
  9674. +
  9675. +static struct irq_chip ar71xx_pci_irq_chip = {
  9676. + .name = "AR71XX PCI ",
  9677. + .mask = ar71xx_pci_irq_mask,
  9678. + .unmask = ar71xx_pci_irq_unmask,
  9679. + .mask_ack = ar71xx_pci_irq_mask,
  9680. +};
  9681. +
  9682. +static void __init ar71xx_pci_irq_init(void)
  9683. +{
  9684. + void __iomem *base = ar71xx_reset_base;
  9685. + int i;
  9686. +
  9687. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
  9688. + __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
  9689. +
  9690. + for (i = AR71XX_PCI_IRQ_BASE;
  9691. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  9692. + irq_desc[i].status = IRQ_DISABLED;
  9693. + set_irq_chip_and_handler(i, &ar71xx_pci_irq_chip,
  9694. + handle_level_irq);
  9695. + }
  9696. +
  9697. + set_irq_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
  9698. +}
  9699. +
  9700. +int __init ar71xx_pcibios_init(void)
  9701. +{
  9702. + void __iomem *ddr_base = ar71xx_ddr_base;
  9703. +
  9704. + ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9705. + ar71xx_pci_delay();
  9706. +
  9707. + ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE);
  9708. + ar71xx_pci_delay();
  9709. +
  9710. + ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE,
  9711. + AR71XX_PCI_CFG_SIZE);
  9712. + if (ar71xx_pcicfg_base == NULL)
  9713. + return -ENOMEM;
  9714. +
  9715. + __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
  9716. + __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
  9717. + __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
  9718. + __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
  9719. + __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
  9720. + __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
  9721. + __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
  9722. + __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
  9723. +
  9724. + ar71xx_pci_delay();
  9725. +
  9726. + /* clear bus errors */
  9727. + (void)ar71xx_pci_be_handler(1);
  9728. +
  9729. + ar71xx_pci_fixup_enable = 1;
  9730. + ar71xx_pci_irq_init();
  9731. + register_pci_controller(&ar71xx_pci_controller);
  9732. +
  9733. + return 0;
  9734. +}
  9735. diff -Nur linux-2.6.37.orig/arch/mips/pci/pci-ar724x.c linux-2.6.37/arch/mips/pci/pci-ar724x.c
  9736. --- linux-2.6.37.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100
  9737. +++ linux-2.6.37/arch/mips/pci/pci-ar724x.c 2011-01-11 20:25:48.000000000 +0100
  9738. @@ -0,0 +1,395 @@
  9739. +/*
  9740. + * Atheros AR724x PCI host controller driver
  9741. + *
  9742. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  9743. + *
  9744. + * Parts of this file are based on Atheros' 2.6.15 BSP
  9745. + *
  9746. + * This program is free software; you can redistribute it and/or modify it
  9747. + * under the terms of the GNU General Public License version 2 as published
  9748. + * by the Free Software Foundation.
  9749. + */
  9750. +
  9751. +#include <linux/resource.h>
  9752. +#include <linux/types.h>
  9753. +#include <linux/delay.h>
  9754. +#include <linux/bitops.h>
  9755. +#include <linux/pci.h>
  9756. +#include <linux/pci_regs.h>
  9757. +#include <linux/interrupt.h>
  9758. +
  9759. +#include <asm/mach-ar71xx/ar71xx.h>
  9760. +#include <asm/mach-ar71xx/pci.h>
  9761. +
  9762. +#undef DEBUG
  9763. +#ifdef DEBUG
  9764. +#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args)
  9765. +#else
  9766. +#define DBG(fmt, args...)
  9767. +#endif
  9768. +
  9769. +static void __iomem *ar724x_pci_localcfg_base;
  9770. +static void __iomem *ar724x_pci_devcfg_base;
  9771. +static void __iomem *ar724x_pci_ctrl_base;
  9772. +static int ar724x_pci_fixup_enable;
  9773. +
  9774. +static DEFINE_SPINLOCK(ar724x_pci_lock);
  9775. +
  9776. +static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value)
  9777. +{
  9778. + unsigned long flags;
  9779. + u32 data;
  9780. +
  9781. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9782. + data = __raw_readl(base + (where & ~3));
  9783. +
  9784. + switch (size) {
  9785. + case 1:
  9786. + if (where & 1)
  9787. + data >>= 8;
  9788. + if (where & 2)
  9789. + data >>= 16;
  9790. + data &= 0xFF;
  9791. + break;
  9792. + case 2:
  9793. + if (where & 2)
  9794. + data >>= 16;
  9795. + data &= 0xFFFF;
  9796. + break;
  9797. + }
  9798. +
  9799. + *value = data;
  9800. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9801. +}
  9802. +
  9803. +static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value)
  9804. +{
  9805. + unsigned long flags;
  9806. + u32 data;
  9807. + int s;
  9808. +
  9809. + spin_lock_irqsave(&ar724x_pci_lock, flags);
  9810. + data = __raw_readl(base + (where & ~3));
  9811. +
  9812. + switch (size) {
  9813. + case 1:
  9814. + s = ((where & 3) << 3);
  9815. + data &= ~(0xFF << s);
  9816. + data |= ((value & 0xFF) << s);
  9817. + break;
  9818. + case 2:
  9819. + s = ((where & 2) << 3);
  9820. + data &= ~(0xFFFF << s);
  9821. + data |= ((value & 0xFFFF) << s);
  9822. + break;
  9823. + case 4:
  9824. + data = value;
  9825. + break;
  9826. + }
  9827. +
  9828. + __raw_writel(data, base + (where & ~3));
  9829. + /* flush write */
  9830. + (void)__raw_readl(base + (where & ~3));
  9831. + spin_unlock_irqrestore(&ar724x_pci_lock, flags);
  9832. +}
  9833. +
  9834. +static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  9835. + int where, int size, u32 *value)
  9836. +{
  9837. +
  9838. + if (bus->number != 0 || devfn != 0)
  9839. + return PCIBIOS_DEVICE_NOT_FOUND;
  9840. +
  9841. + ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value);
  9842. +
  9843. + DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9844. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9845. + where, size, *value);
  9846. +
  9847. + /*
  9848. + * WAR for BAR issue - We are unable to access the PCI device space
  9849. + * if we set the BAR with proper base address
  9850. + */
  9851. + if ((where == 0x10) && (size == 4)) {
  9852. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9853. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0xffff);
  9854. + else
  9855. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0x1000ffff);
  9856. + }
  9857. +
  9858. + return PCIBIOS_SUCCESSFUL;
  9859. +}
  9860. +
  9861. +static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  9862. + int where, int size, u32 value)
  9863. +{
  9864. + if (bus->number != 0 || devfn != 0)
  9865. + return PCIBIOS_DEVICE_NOT_FOUND;
  9866. +
  9867. + DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n",
  9868. + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
  9869. + where, size, value);
  9870. +
  9871. + ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value);
  9872. +
  9873. + return PCIBIOS_SUCCESSFUL;
  9874. +}
  9875. +
  9876. +static void ar724x_pci_fixup(struct pci_dev *dev)
  9877. +{
  9878. + u16 cmd;
  9879. +
  9880. + if (!ar724x_pci_fixup_enable)
  9881. + return;
  9882. +
  9883. + if (dev->bus->number != 0 || dev->devfn != 0)
  9884. + return;
  9885. +
  9886. + /* setup COMMAND register */
  9887. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  9888. + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
  9889. + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
  9890. + PCI_COMMAND_FAST_BACK;
  9891. +
  9892. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  9893. +}
  9894. +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup);
  9895. +
  9896. +int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot,
  9897. + uint8_t pin)
  9898. +{
  9899. + int irq = -1;
  9900. + int i;
  9901. +
  9902. + for (i = 0; i < ar71xx_pci_nr_irqs; i++) {
  9903. + struct ar71xx_pci_irq *entry;
  9904. + entry = &ar71xx_pci_irq_map[i];
  9905. +
  9906. + if (entry->slot == slot && entry->pin == pin) {
  9907. + irq = entry->irq;
  9908. + break;
  9909. + }
  9910. + }
  9911. +
  9912. + if (irq < 0)
  9913. + printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n",
  9914. + pin, pci_name((struct pci_dev *)dev));
  9915. + else
  9916. + printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n",
  9917. + irq, pin, pci_name((struct pci_dev *)dev));
  9918. +
  9919. + return irq;
  9920. +}
  9921. +
  9922. +static struct pci_ops ar724x_pci_ops = {
  9923. + .read = ar724x_pci_read_config,
  9924. + .write = ar724x_pci_write_config,
  9925. +};
  9926. +
  9927. +static struct resource ar724x_pci_io_resource = {
  9928. + .name = "PCI IO space",
  9929. + .start = 0,
  9930. + .end = 0,
  9931. + .flags = IORESOURCE_IO,
  9932. +};
  9933. +
  9934. +static struct resource ar724x_pci_mem_resource = {
  9935. + .name = "PCI memory space",
  9936. + .start = AR71XX_PCI_MEM_BASE,
  9937. + .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
  9938. + .flags = IORESOURCE_MEM
  9939. +};
  9940. +
  9941. +static struct pci_controller ar724x_pci_controller = {
  9942. + .pci_ops = &ar724x_pci_ops,
  9943. + .mem_resource = &ar724x_pci_mem_resource,
  9944. + .io_resource = &ar724x_pci_io_resource,
  9945. +};
  9946. +
  9947. +static void __init ar724x_pci_reset(void)
  9948. +{
  9949. + ar71xx_device_stop(AR724X_RESET_PCIE);
  9950. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY);
  9951. + ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL);
  9952. + udelay(100);
  9953. +
  9954. + ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL);
  9955. + udelay(100);
  9956. + ar71xx_device_start(AR724X_RESET_PCIE_PHY);
  9957. + ar71xx_device_start(AR724X_RESET_PCIE);
  9958. +}
  9959. +
  9960. +static int __init ar724x_pci_setup(void)
  9961. +{
  9962. + void __iomem *base = ar724x_pci_ctrl_base;
  9963. + u32 t;
  9964. +
  9965. + /* setup COMMAND register */
  9966. + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE |
  9967. + PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK;
  9968. +
  9969. + ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t);
  9970. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000);
  9971. + ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000);
  9972. +
  9973. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9974. + if (t != 0x7) {
  9975. + udelay(100000);
  9976. + __raw_writel(0, base + AR724X_PCI_REG_RESET);
  9977. + udelay(100);
  9978. + __raw_writel(4, base + AR724X_PCI_REG_RESET);
  9979. + udelay(100000);
  9980. + }
  9981. +
  9982. + if (ar71xx_soc == AR71XX_SOC_AR7240)
  9983. + t = AR724X_PCI_APP_LTSSM_ENABLE;
  9984. + else
  9985. + t = 0x1ffc1;
  9986. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  9987. + /* flush write */
  9988. + (void) __raw_readl(base + AR724X_PCI_REG_APP);
  9989. + udelay(1000);
  9990. +
  9991. + t = __raw_readl(base + AR724X_PCI_REG_RESET);
  9992. + if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) {
  9993. + printk(KERN_WARNING "PCI: no PCIe module found\n");
  9994. + return -ENODEV;
  9995. + }
  9996. +
  9997. + if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
  9998. + t = __raw_readl(base + AR724X_PCI_REG_APP);
  9999. + t |= BIT(16);
  10000. + __raw_writel(t, base + AR724X_PCI_REG_APP);
  10001. + }
  10002. +
  10003. + return 0;
  10004. +}
  10005. +
  10006. +static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
  10007. +{
  10008. + void __iomem *base = ar724x_pci_ctrl_base;
  10009. + u32 pending;
  10010. +
  10011. + pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
  10012. + __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10013. +
  10014. + if (pending & AR724X_PCI_INT_DEV0)
  10015. + generic_handle_irq(AR71XX_PCI_IRQ_DEV0);
  10016. +
  10017. + else
  10018. + spurious_interrupt();
  10019. +}
  10020. +
  10021. +static void ar724x_pci_irq_unmask(unsigned int irq)
  10022. +{
  10023. + void __iomem *base = ar724x_pci_ctrl_base;
  10024. + u32 t;
  10025. +
  10026. + switch (irq) {
  10027. + case AR71XX_PCI_IRQ_DEV0:
  10028. + irq -= AR71XX_PCI_IRQ_BASE;
  10029. +
  10030. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10031. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  10032. + base + AR724X_PCI_REG_INT_MASK);
  10033. + /* flush write */
  10034. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10035. + }
  10036. +}
  10037. +
  10038. +static void ar724x_pci_irq_mask(unsigned int irq)
  10039. +{
  10040. + void __iomem *base = ar724x_pci_ctrl_base;
  10041. + u32 t;
  10042. +
  10043. + switch (irq) {
  10044. + case AR71XX_PCI_IRQ_DEV0:
  10045. + irq -= AR71XX_PCI_IRQ_BASE;
  10046. +
  10047. + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10048. + __raw_writel(t & ~AR724X_PCI_INT_DEV0,
  10049. + base + AR724X_PCI_REG_INT_MASK);
  10050. +
  10051. + /* flush write */
  10052. + (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK);
  10053. +
  10054. + t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  10055. + __raw_writel(t | AR724X_PCI_INT_DEV0,
  10056. + base + AR724X_PCI_REG_INT_STATUS);
  10057. +
  10058. + /* flush write */
  10059. + (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
  10060. + }
  10061. +}
  10062. +
  10063. +static struct irq_chip ar724x_pci_irq_chip = {
  10064. + .name = "AR724X PCI ",
  10065. + .mask = ar724x_pci_irq_mask,
  10066. + .unmask = ar724x_pci_irq_unmask,
  10067. + .mask_ack = ar724x_pci_irq_mask,
  10068. +};
  10069. +
  10070. +static void __init ar724x_pci_irq_init(void)
  10071. +{
  10072. + void __iomem *base = ar724x_pci_ctrl_base;
  10073. + u32 t;
  10074. + int i;
  10075. +
  10076. + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
  10077. + if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY |
  10078. + AR724X_RESET_PCIE_PHY_SERIAL)) {
  10079. + return;
  10080. + }
  10081. +
  10082. + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
  10083. + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
  10084. +
  10085. + for (i = AR71XX_PCI_IRQ_BASE;
  10086. + i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
  10087. + irq_desc[i].status = IRQ_DISABLED;
  10088. + set_irq_chip_and_handler(i, &ar724x_pci_irq_chip,
  10089. + handle_level_irq);
  10090. + }
  10091. +
  10092. + set_irq_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler);
  10093. +}
  10094. +
  10095. +int __init ar724x_pcibios_init(void)
  10096. +{
  10097. + int ret = -ENOMEM;
  10098. +
  10099. + ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE,
  10100. + AR724X_PCI_CRP_SIZE);
  10101. + if (ar724x_pci_localcfg_base == NULL)
  10102. + goto err;
  10103. +
  10104. + ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE,
  10105. + AR724X_PCI_CFG_SIZE);
  10106. + if (ar724x_pci_devcfg_base == NULL)
  10107. + goto err_unmap_localcfg;
  10108. +
  10109. + ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE,
  10110. + AR724X_PCI_CTRL_SIZE);
  10111. + if (ar724x_pci_ctrl_base == NULL)
  10112. + goto err_unmap_devcfg;
  10113. +
  10114. + ar724x_pci_reset();
  10115. + ret = ar724x_pci_setup();
  10116. + if (ret)
  10117. + goto err_unmap_ctrl;
  10118. +
  10119. + ar724x_pci_fixup_enable = 1;
  10120. + ar724x_pci_irq_init();
  10121. + register_pci_controller(&ar724x_pci_controller);
  10122. +
  10123. + return 0;
  10124. +
  10125. + err_unmap_ctrl:
  10126. + iounmap(ar724x_pci_ctrl_base);
  10127. + err_unmap_devcfg:
  10128. + iounmap(ar724x_pci_devcfg_base);
  10129. + err_unmap_localcfg:
  10130. + iounmap(ar724x_pci_localcfg_base);
  10131. + err:
  10132. + return ret;
  10133. +}
  10134. diff -Nur linux-2.6.37.orig/drivers/char/Kconfig linux-2.6.37/drivers/char/Kconfig
  10135. --- linux-2.6.37.orig/drivers/char/Kconfig 2011-01-05 01:50:19.000000000 +0100
  10136. +++ linux-2.6.37/drivers/char/Kconfig 2011-01-11 20:25:48.000000000 +0100
  10137. @@ -1047,6 +1047,14 @@
  10138. If compiled as a module, it will be called cs5535_gpio.
  10139. +config GPIO_DEVICE
  10140. + tristate "GPIO device support"
  10141. + depends on GENERIC_GPIO
  10142. + help
  10143. + Say Y to enable Linux GPIO device support. This allows control of
  10144. + GPIO pins using a character device
  10145. +
  10146. +
  10147. config RAW_DRIVER
  10148. tristate "RAW driver (/dev/raw/rawN)"
  10149. depends on BLOCK
  10150. diff -Nur linux-2.6.37.orig/drivers/char/Makefile linux-2.6.37/drivers/char/Makefile
  10151. --- linux-2.6.37.orig/drivers/char/Makefile 2011-01-05 01:50:19.000000000 +0100
  10152. +++ linux-2.6.37/drivers/char/Makefile 2011-01-11 20:25:48.000000000 +0100
  10153. @@ -82,6 +82,7 @@
  10154. obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
  10155. obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
  10156. obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
  10157. +obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o
  10158. obj-$(CONFIG_GPIO_TB0219) += tb0219.o
  10159. obj-$(CONFIG_TELCLOCK) += tlclk.o
  10160. diff -Nur linux-2.6.37.orig/drivers/gpio/nxp_74hc153.c linux-2.6.37/drivers/gpio/nxp_74hc153.c
  10161. --- linux-2.6.37.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100
  10162. +++ linux-2.6.37/drivers/gpio/nxp_74hc153.c 2011-01-11 20:25:48.000000000 +0100
  10163. @@ -0,0 +1,246 @@
  10164. +/*
  10165. + * NXP 74HC153 - Dual 4-input multiplexer GPIO driver
  10166. + *
  10167. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  10168. + *
  10169. + * This program is free software; you can redistribute it and/or modify
  10170. + * it under the terms of the GNU General Public License version 2 as
  10171. + * published by the Free Software Foundation.
  10172. + */
  10173. +
  10174. +#include <linux/module.h>
  10175. +#include <linux/init.h>
  10176. +#include <linux/gpio.h>
  10177. +#include <linux/platform_device.h>
  10178. +#include <linux/nxp_74hc153.h>
  10179. +
  10180. +#define NXP_74HC153_NUM_GPIOS 8
  10181. +#define NXP_74HC153_S0_MASK 0x1
  10182. +#define NXP_74HC153_S1_MASK 0x2
  10183. +#define NXP_74HC153_BANK_MASK 0x4
  10184. +
  10185. +struct nxp_74hc153_chip {
  10186. + struct device *parent;
  10187. + struct gpio_chip gpio_chip;
  10188. + struct mutex lock;
  10189. +};
  10190. +
  10191. +static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc)
  10192. +{
  10193. + return container_of(gc, struct nxp_74hc153_chip, gpio_chip);
  10194. +}
  10195. +
  10196. +static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset)
  10197. +{
  10198. + return 0;
  10199. +}
  10200. +
  10201. +static int nxp_74hc153_direction_output(struct gpio_chip *gc,
  10202. + unsigned offset, int val)
  10203. +{
  10204. + return -EINVAL;
  10205. +}
  10206. +
  10207. +static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset)
  10208. +{
  10209. + struct nxp_74hc153_chip *nxp;
  10210. + struct nxp_74hc153_platform_data *pdata;
  10211. + unsigned s0;
  10212. + unsigned s1;
  10213. + unsigned pin;
  10214. + int ret;
  10215. +
  10216. + nxp = gpio_to_nxp(gc);
  10217. + pdata = nxp->parent->platform_data;
  10218. +
  10219. + s0 = !!(offset & NXP_74HC153_S0_MASK);
  10220. + s1 = !!(offset & NXP_74HC153_S1_MASK);
  10221. + pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y
  10222. + : pdata->gpio_pin_1y;
  10223. +
  10224. + mutex_lock(&nxp->lock);
  10225. + gpio_set_value(pdata->gpio_pin_s0, s0);
  10226. + gpio_set_value(pdata->gpio_pin_s1, s1);
  10227. + ret = gpio_get_value(pin);
  10228. + mutex_unlock(&nxp->lock);
  10229. +
  10230. + return ret;
  10231. +}
  10232. +
  10233. +static void nxp_74hc153_set_value(struct gpio_chip *gc,
  10234. + unsigned offset, int val)
  10235. +{
  10236. + /* not supported */
  10237. +}
  10238. +
  10239. +static int __devinit nxp_74hc153_probe(struct platform_device *pdev)
  10240. +{
  10241. + struct nxp_74hc153_platform_data *pdata;
  10242. + struct nxp_74hc153_chip *nxp;
  10243. + struct gpio_chip *gc;
  10244. + int err;
  10245. +
  10246. + pdata = pdev->dev.platform_data;
  10247. + if (pdata == NULL) {
  10248. + dev_dbg(&pdev->dev, "no platform data specified\n");
  10249. + return -EINVAL;
  10250. + }
  10251. +
  10252. + nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL);
  10253. + if (nxp == NULL) {
  10254. + dev_err(&pdev->dev, "no memory for private data\n");
  10255. + return -ENOMEM;
  10256. + }
  10257. +
  10258. + err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev));
  10259. + if (err) {
  10260. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10261. + pdata->gpio_pin_s0, err);
  10262. + goto err_free_nxp;
  10263. + }
  10264. +
  10265. + err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev));
  10266. + if (err) {
  10267. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10268. + pdata->gpio_pin_s1, err);
  10269. + goto err_free_s0;
  10270. + }
  10271. +
  10272. + err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev));
  10273. + if (err) {
  10274. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10275. + pdata->gpio_pin_1y, err);
  10276. + goto err_free_s1;
  10277. + }
  10278. +
  10279. + err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev));
  10280. + if (err) {
  10281. + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
  10282. + pdata->gpio_pin_2y, err);
  10283. + goto err_free_1y;
  10284. + }
  10285. +
  10286. + err = gpio_direction_output(pdata->gpio_pin_s0, 0);
  10287. + if (err) {
  10288. + dev_err(&pdev->dev,
  10289. + "unable to set direction of gpio %u, err=%d\n",
  10290. + pdata->gpio_pin_s0, err);
  10291. + goto err_free_2y;
  10292. + }
  10293. +
  10294. + err = gpio_direction_output(pdata->gpio_pin_s1, 0);
  10295. + if (err) {
  10296. + dev_err(&pdev->dev,
  10297. + "unable to set direction of gpio %u, err=%d\n",
  10298. + pdata->gpio_pin_s1, err);
  10299. + goto err_free_2y;
  10300. + }
  10301. +
  10302. + err = gpio_direction_input(pdata->gpio_pin_1y);
  10303. + if (err) {
  10304. + dev_err(&pdev->dev,
  10305. + "unable to set direction of gpio %u, err=%d\n",
  10306. + pdata->gpio_pin_1y, err);
  10307. + goto err_free_2y;
  10308. + }
  10309. +
  10310. + err = gpio_direction_input(pdata->gpio_pin_2y);
  10311. + if (err) {
  10312. + dev_err(&pdev->dev,
  10313. + "unable to set direction of gpio %u, err=%d\n",
  10314. + pdata->gpio_pin_2y, err);
  10315. + goto err_free_2y;
  10316. + }
  10317. +
  10318. + nxp->parent = &pdev->dev;
  10319. + mutex_init(&nxp->lock);
  10320. +
  10321. + gc = &nxp->gpio_chip;
  10322. +
  10323. + gc->direction_input = nxp_74hc153_direction_input;
  10324. + gc->direction_output = nxp_74hc153_direction_output;
  10325. + gc->get = nxp_74hc153_get_value;
  10326. + gc->set = nxp_74hc153_set_value;
  10327. + gc->can_sleep = 1;
  10328. +
  10329. + gc->base = pdata->gpio_base;
  10330. + gc->ngpio = NXP_74HC153_NUM_GPIOS;
  10331. + gc->label = dev_name(nxp->parent);
  10332. + gc->dev = nxp->parent;
  10333. + gc->owner = THIS_MODULE;
  10334. +
  10335. + err = gpiochip_add(&nxp->gpio_chip);
  10336. + if (err) {
  10337. + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
  10338. + goto err_free_2y;
  10339. + }
  10340. +
  10341. + platform_set_drvdata(pdev, nxp);
  10342. + return 0;
  10343. +
  10344. + err_free_2y:
  10345. + gpio_free(pdata->gpio_pin_2y);
  10346. + err_free_1y:
  10347. + gpio_free(pdata->gpio_pin_1y);
  10348. + err_free_s1:
  10349. + gpio_free(pdata->gpio_pin_s1);
  10350. + err_free_s0:
  10351. + gpio_free(pdata->gpio_pin_s0);
  10352. + err_free_nxp:
  10353. + kfree(nxp);
  10354. + return err;
  10355. +}
  10356. +
  10357. +static int nxp_74hc153_remove(struct platform_device *pdev)
  10358. +{
  10359. + struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev);
  10360. + struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data;
  10361. +
  10362. + if (nxp) {
  10363. + int err;
  10364. +
  10365. + err = gpiochip_remove(&nxp->gpio_chip);
  10366. + if (err) {
  10367. + dev_err(&pdev->dev,
  10368. + "unable to remove gpio chip, err=%d\n",
  10369. + err);
  10370. + return err;
  10371. + }
  10372. +
  10373. + gpio_free(pdata->gpio_pin_2y);
  10374. + gpio_free(pdata->gpio_pin_1y);
  10375. + gpio_free(pdata->gpio_pin_s1);
  10376. + gpio_free(pdata->gpio_pin_s0);
  10377. +
  10378. + kfree(nxp);
  10379. + platform_set_drvdata(pdev, NULL);
  10380. + }
  10381. +
  10382. + return 0;
  10383. +}
  10384. +
  10385. +static struct platform_driver nxp_74hc153_driver = {
  10386. + .probe = nxp_74hc153_probe,
  10387. + .remove = __devexit_p(nxp_74hc153_remove),
  10388. + .driver = {
  10389. + .name = NXP_74HC153_DRIVER_NAME,
  10390. + .owner = THIS_MODULE,
  10391. + },
  10392. +};
  10393. +
  10394. +static int __init nxp_74hc153_init(void)
  10395. +{
  10396. + return platform_driver_register(&nxp_74hc153_driver);
  10397. +}
  10398. +subsys_initcall(nxp_74hc153_init);
  10399. +
  10400. +static void __exit nxp_74hc153_exit(void)
  10401. +{
  10402. + platform_driver_unregister(&nxp_74hc153_driver);
  10403. +}
  10404. +module_exit(nxp_74hc153_exit);
  10405. +
  10406. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10407. +MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153");
  10408. +MODULE_LICENSE("GPL v2");
  10409. +MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME);
  10410. diff -Nur linux-2.6.37.orig/drivers/input/misc/Kconfig linux-2.6.37/drivers/input/misc/Kconfig
  10411. --- linux-2.6.37.orig/drivers/input/misc/Kconfig 2011-01-05 01:50:19.000000000 +0100
  10412. +++ linux-2.6.37/drivers/input/misc/Kconfig 2011-01-11 20:25:48.000000000 +0100
  10413. @@ -448,4 +448,20 @@
  10414. To compile this driver as a module, choose M here: the
  10415. module will be called adxl34x-spi.
  10416. +config INPUT_GPIO_BUTTONS
  10417. + tristate "Polled GPIO buttons interface"
  10418. + depends on GENERIC_GPIO
  10419. + select INPUT_POLLDEV
  10420. + help
  10421. + This driver implements support for buttons connected
  10422. + to GPIO pins of various CPUs (and some other chips).
  10423. +
  10424. + Say Y here if your device has buttons connected
  10425. + directly to such GPIO pins. Your board-specific
  10426. + setup logic must also provide a platform device,
  10427. + with configuration data saying which GPIOs are used.
  10428. +
  10429. + To compile this driver as a module, choose M here: the
  10430. + module will be called gpio-buttons.
  10431. +
  10432. endif
  10433. diff -Nur linux-2.6.37.orig/drivers/input/misc/Makefile linux-2.6.37/drivers/input/misc/Makefile
  10434. --- linux-2.6.37.orig/drivers/input/misc/Makefile 2011-01-05 01:50:19.000000000 +0100
  10435. +++ linux-2.6.37/drivers/input/misc/Makefile 2011-01-11 20:25:48.000000000 +0100
  10436. @@ -42,4 +42,5 @@
  10437. obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
  10438. obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
  10439. obj-$(CONFIG_INPUT_YEALINK) += yealink.o
  10440. +obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o
  10441. diff -Nur linux-2.6.37.orig/drivers/input/misc/gpio_buttons.c linux-2.6.37/drivers/input/misc/gpio_buttons.c
  10442. --- linux-2.6.37.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100
  10443. +++ linux-2.6.37/drivers/input/misc/gpio_buttons.c 2011-01-11 20:25:48.000000000 +0100
  10444. @@ -0,0 +1,216 @@
  10445. +/*
  10446. + * Driver for buttons on GPIO lines not capable of generating interrupts
  10447. + *
  10448. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  10449. + * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
  10450. + *
  10451. + * This file was based on: /drivers/input/misc/cobalt_btns.c
  10452. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  10453. + *
  10454. + * also was based on: /drivers/input/keyboard/gpio_keys.c
  10455. + * Copyright 2005 Phil Blundell
  10456. + *
  10457. + * This program is free software; you can redistribute it and/or modify
  10458. + * it under the terms of the GNU General Public License version 2 as
  10459. + * published by the Free Software Foundation.
  10460. + *
  10461. + */
  10462. +
  10463. +#include <linux/kernel.h>
  10464. +#include <linux/module.h>
  10465. +#include <linux/init.h>
  10466. +#include <linux/slab.h>
  10467. +
  10468. +#include <linux/input.h>
  10469. +#include <linux/input-polldev.h>
  10470. +#include <linux/ioport.h>
  10471. +#include <linux/platform_device.h>
  10472. +
  10473. +#include <linux/gpio_buttons.h>
  10474. +
  10475. +#include <asm/gpio.h>
  10476. +
  10477. +#define DRV_NAME "gpio-buttons"
  10478. +#define DRV_VERSION "0.1.2"
  10479. +#define PFX DRV_NAME ": "
  10480. +
  10481. +struct gpio_button_data {
  10482. + int last_state;
  10483. + int count;
  10484. +};
  10485. +
  10486. +struct gpio_buttons_dev {
  10487. + struct input_polled_dev *poll_dev;
  10488. + struct gpio_buttons_platform_data *pdata;
  10489. + struct gpio_button_data *data;
  10490. +};
  10491. +
  10492. +static void gpio_buttons_poll(struct input_polled_dev *dev)
  10493. +{
  10494. + struct gpio_buttons_dev *bdev = dev->private;
  10495. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10496. + struct input_dev *input = dev->input;
  10497. + int i;
  10498. +
  10499. + for (i = 0; i < bdev->pdata->nbuttons; i++) {
  10500. + struct gpio_button *button = &pdata->buttons[i];
  10501. + unsigned int type = button->type ?: EV_KEY;
  10502. + int state;
  10503. +
  10504. + if (bdev->data[i].count < button->threshold) {
  10505. + bdev->data[i].count++;
  10506. + continue;
  10507. + }
  10508. +
  10509. + state = gpio_get_value(button->gpio) ? 1 : 0;
  10510. + if (state != bdev->data[i].last_state) {
  10511. + input_event(input, type, button->code,
  10512. + !!(state ^ button->active_low));
  10513. + input_sync(input);
  10514. + bdev->data[i].count = 0;
  10515. + bdev->data[i].last_state = state;
  10516. + }
  10517. + }
  10518. +}
  10519. +
  10520. +static int __devinit gpio_buttons_probe(struct platform_device *pdev)
  10521. +{
  10522. + struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data;
  10523. + struct gpio_buttons_dev *bdev;
  10524. + struct input_polled_dev *poll_dev;
  10525. + struct input_dev *input;
  10526. + int error, i;
  10527. +
  10528. + if (!pdata)
  10529. + return -ENXIO;
  10530. +
  10531. + bdev = kzalloc(sizeof(struct gpio_buttons_dev) +
  10532. + sizeof(struct gpio_button_data) * pdata->nbuttons,
  10533. + GFP_KERNEL);
  10534. + if (!bdev) {
  10535. + printk(KERN_ERR DRV_NAME "no memory for device\n");
  10536. + return -ENOMEM;
  10537. + }
  10538. +
  10539. + bdev->data = (struct gpio_button_data *) &bdev[1];
  10540. +
  10541. + poll_dev = input_allocate_polled_device();
  10542. + if (!poll_dev) {
  10543. + printk(KERN_ERR DRV_NAME "no memory for polled device\n");
  10544. + error = -ENOMEM;
  10545. + goto err_free_bdev;
  10546. + }
  10547. +
  10548. + poll_dev->private = bdev;
  10549. + poll_dev->poll = gpio_buttons_poll;
  10550. + poll_dev->poll_interval = pdata->poll_interval;
  10551. +
  10552. + input = poll_dev->input;
  10553. +
  10554. + input->evbit[0] = BIT(EV_KEY);
  10555. + input->name = pdev->name;
  10556. + input->phys = "gpio-buttons/input0";
  10557. + input->dev.parent = &pdev->dev;
  10558. +
  10559. + input->id.bustype = BUS_HOST;
  10560. + input->id.vendor = 0x0001;
  10561. + input->id.product = 0x0001;
  10562. + input->id.version = 0x0100;
  10563. +
  10564. + for (i = 0; i < pdata->nbuttons; i++) {
  10565. + struct gpio_button *button = &pdata->buttons[i];
  10566. + unsigned int gpio = button->gpio;
  10567. + unsigned int type = button->type ?: EV_KEY;
  10568. +
  10569. + error = gpio_request(gpio, button->desc ?
  10570. + button->desc : DRV_NAME);
  10571. + if (error) {
  10572. + printk(KERN_ERR PFX "unable to claim gpio %u, "
  10573. + "error %d\n", gpio, error);
  10574. + goto err_free_gpio;
  10575. + }
  10576. +
  10577. + error = gpio_direction_input(gpio);
  10578. + if (error) {
  10579. + printk(KERN_ERR PFX "unable to set direction on "
  10580. + "gpio %u, error %d\n", gpio, error);
  10581. + goto err_free_gpio;
  10582. + }
  10583. +
  10584. + input_set_capability(input, type, button->code);
  10585. + bdev->data[i].last_state = gpio_get_value(button->gpio) ? 1 : 0;
  10586. + }
  10587. +
  10588. + bdev->poll_dev = poll_dev;
  10589. + bdev->pdata = pdata;
  10590. + platform_set_drvdata(pdev, bdev);
  10591. +
  10592. + error = input_register_polled_device(poll_dev);
  10593. + if (error) {
  10594. + printk(KERN_ERR PFX "unable to register polled device, "
  10595. + "error %d\n", error);
  10596. + goto err_free_gpio;
  10597. + }
  10598. +
  10599. + return 0;
  10600. +
  10601. +err_free_gpio:
  10602. + for (i = i - 1; i >= 0; i--)
  10603. + gpio_free(pdata->buttons[i].gpio);
  10604. +
  10605. + input_free_polled_device(poll_dev);
  10606. +
  10607. +err_free_bdev:
  10608. + kfree(bdev);
  10609. +
  10610. + platform_set_drvdata(pdev, NULL);
  10611. + return error;
  10612. +}
  10613. +
  10614. +static int __devexit gpio_buttons_remove(struct platform_device *pdev)
  10615. +{
  10616. + struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev);
  10617. + struct gpio_buttons_platform_data *pdata = bdev->pdata;
  10618. + int i;
  10619. +
  10620. + input_unregister_polled_device(bdev->poll_dev);
  10621. +
  10622. + for (i = 0; i < pdata->nbuttons; i++)
  10623. + gpio_free(pdata->buttons[i].gpio);
  10624. +
  10625. + input_free_polled_device(bdev->poll_dev);
  10626. +
  10627. + kfree(bdev);
  10628. + platform_set_drvdata(pdev, NULL);
  10629. +
  10630. + return 0;
  10631. +}
  10632. +
  10633. +static struct platform_driver gpio_buttons_driver = {
  10634. + .probe = gpio_buttons_probe,
  10635. + .remove = __devexit_p(gpio_buttons_remove),
  10636. + .driver = {
  10637. + .name = DRV_NAME,
  10638. + .owner = THIS_MODULE,
  10639. + },
  10640. +};
  10641. +
  10642. +static int __init gpio_buttons_init(void)
  10643. +{
  10644. + printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n");
  10645. + return platform_driver_register(&gpio_buttons_driver);
  10646. +}
  10647. +
  10648. +static void __exit gpio_buttons_exit(void)
  10649. +{
  10650. + platform_driver_unregister(&gpio_buttons_driver);
  10651. +}
  10652. +
  10653. +module_init(gpio_buttons_init);
  10654. +module_exit(gpio_buttons_exit);
  10655. +
  10656. +MODULE_LICENSE("GPL");
  10657. +MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
  10658. +MODULE_VERSION(DRV_VERSION);
  10659. +MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs");
  10660. +
  10661. diff -Nur linux-2.6.37.orig/drivers/leds/leds-rb750.c linux-2.6.37/drivers/leds/leds-rb750.c
  10662. --- linux-2.6.37.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100
  10663. +++ linux-2.6.37/drivers/leds/leds-rb750.c 2011-01-11 20:25:48.000000000 +0100
  10664. @@ -0,0 +1,140 @@
  10665. +/*
  10666. + * LED driver for the RouterBOARD 750
  10667. + *
  10668. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  10669. + *
  10670. + * This program is free software; you can redistribute it and/or modify
  10671. + * it under the terms of the GNU General Public License version 2 as
  10672. + * published by the Free Software Foundation.
  10673. + *
  10674. + */
  10675. +#include <linux/kernel.h>
  10676. +#include <linux/init.h>
  10677. +#include <linux/platform_device.h>
  10678. +#include <linux/leds.h>
  10679. +
  10680. +#include <asm/mach-ar71xx/mach-rb750.h>
  10681. +
  10682. +#define DRV_NAME "leds-rb750"
  10683. +
  10684. +struct rb750_led_dev {
  10685. + struct led_classdev cdev;
  10686. + u32 mask;
  10687. + int active_low;
  10688. +};
  10689. +
  10690. +struct rb750_led_drvdata {
  10691. + struct rb750_led_dev *led_devs;
  10692. + int num_leds;
  10693. +};
  10694. +
  10695. +static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev)
  10696. +{
  10697. + return (struct rb750_led_dev *)container_of(led_cdev,
  10698. + struct rb750_led_dev, cdev);
  10699. +}
  10700. +
  10701. +static void rb750_led_brightness_set(struct led_classdev *led_cdev,
  10702. + enum led_brightness value)
  10703. +{
  10704. + struct rb750_led_dev *rbled = to_rbled(led_cdev);
  10705. + int level;
  10706. +
  10707. + level = (value == LED_OFF) ? 0 : 1;
  10708. + level ^= rbled->active_low;
  10709. +
  10710. + if (level)
  10711. + rb750_latch_change(0, rbled->mask);
  10712. + else
  10713. + rb750_latch_change(rbled->mask, 0);
  10714. +}
  10715. +
  10716. +static int __devinit rb750_led_probe(struct platform_device *pdev)
  10717. +{
  10718. + struct rb750_led_platform_data *pdata;
  10719. + struct rb750_led_drvdata *drvdata;
  10720. + int ret = 0;
  10721. + int i;
  10722. +
  10723. + pdata = pdev->dev.platform_data;
  10724. + if (!pdata)
  10725. + return -EINVAL;
  10726. +
  10727. + drvdata = kzalloc(sizeof(struct rb750_led_drvdata) +
  10728. + sizeof(struct rb750_led_dev) * pdata->num_leds,
  10729. + GFP_KERNEL);
  10730. + if (!drvdata)
  10731. + return -ENOMEM;
  10732. +
  10733. + drvdata->num_leds = pdata->num_leds;
  10734. + drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1];
  10735. +
  10736. + for (i = 0; i < drvdata->num_leds; i++) {
  10737. + struct rb750_led_dev *rbled = &drvdata->led_devs[i];
  10738. + struct rb750_led_data *led_data = &pdata->leds[i];
  10739. +
  10740. + rbled->cdev.name = led_data->name;
  10741. + rbled->cdev.default_trigger = led_data->default_trigger;
  10742. + rbled->cdev.brightness_set = rb750_led_brightness_set;
  10743. + rbled->cdev.brightness = LED_OFF;
  10744. +
  10745. + rbled->mask = led_data->mask;
  10746. + rbled->active_low = !!led_data->active_low;
  10747. +
  10748. + ret = led_classdev_register(&pdev->dev, &rbled->cdev);
  10749. + if (ret)
  10750. + goto err;
  10751. + }
  10752. +
  10753. + platform_set_drvdata(pdev, drvdata);
  10754. + return 0;
  10755. +
  10756. + err:
  10757. + for (i = i - 1; i >= 0; i--)
  10758. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10759. +
  10760. + kfree(drvdata);
  10761. + return ret;
  10762. +}
  10763. +
  10764. +static int __devexit rb750_led_remove(struct platform_device *pdev)
  10765. +{
  10766. + struct rb750_led_drvdata *drvdata;
  10767. + int i;
  10768. +
  10769. + drvdata = platform_get_drvdata(pdev);
  10770. + for (i = 0; i < drvdata->num_leds; i++)
  10771. + led_classdev_unregister(&drvdata->led_devs[i].cdev);
  10772. +
  10773. + kfree(drvdata);
  10774. + return 0;
  10775. +}
  10776. +
  10777. +static struct platform_driver rb750_led_driver = {
  10778. + .probe = rb750_led_probe,
  10779. + .remove = __devexit_p(rb750_led_remove),
  10780. + .driver = {
  10781. + .name = DRV_NAME,
  10782. + .owner = THIS_MODULE,
  10783. + },
  10784. +};
  10785. +
  10786. +MODULE_ALIAS("platform:leds-rb750");
  10787. +
  10788. +static int __init rb750_led_init(void)
  10789. +{
  10790. + return platform_driver_register(&rb750_led_driver);
  10791. +}
  10792. +
  10793. +static void __exit rb750_led_exit(void)
  10794. +{
  10795. + platform_driver_unregister(&rb750_led_driver);
  10796. +}
  10797. +
  10798. +module_init(rb750_led_init);
  10799. +module_exit(rb750_led_exit);
  10800. +
  10801. +MODULE_DESCRIPTION(DRV_NAME);
  10802. +MODULE_DESCRIPTION("LED driver for the RouterBOARD 750");
  10803. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10804. +MODULE_LICENSE("GPL v2");
  10805. diff -Nur linux-2.6.37.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.37/drivers/leds/leds-wndr3700-usb.c
  10806. --- linux-2.6.37.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100
  10807. +++ linux-2.6.37/drivers/leds/leds-wndr3700-usb.c 2011-01-11 20:25:48.000000000 +0100
  10808. @@ -0,0 +1,75 @@
  10809. +/*
  10810. + * USB LED driver for the NETGEAR WNDR3700
  10811. + *
  10812. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10813. + *
  10814. + * This program is free software; you can redistribute it and/or modify it
  10815. + * under the terms of the GNU General Public License version 2 as published
  10816. + * by the Free Software Foundation.
  10817. + */
  10818. +
  10819. +#include <linux/leds.h>
  10820. +#include <linux/module.h>
  10821. +#include <linux/platform_device.h>
  10822. +
  10823. +#include <asm/mach-ar71xx/ar71xx.h>
  10824. +
  10825. +#define DRIVER_NAME "wndr3700-led-usb"
  10826. +
  10827. +static void wndr3700_usb_led_set(struct led_classdev *cdev,
  10828. + enum led_brightness brightness)
  10829. +{
  10830. + if (brightness)
  10831. + ar71xx_device_start(RESET_MODULE_GE1_PHY);
  10832. + else
  10833. + ar71xx_device_stop(RESET_MODULE_GE1_PHY);
  10834. +}
  10835. +
  10836. +static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev)
  10837. +{
  10838. + return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL;
  10839. +}
  10840. +
  10841. +static struct led_classdev wndr3700_usb_led = {
  10842. + .name = "wndr3700:green:usb",
  10843. + .brightness_set = wndr3700_usb_led_set,
  10844. + .brightness_get = wndr3700_usb_led_get,
  10845. +};
  10846. +
  10847. +static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev)
  10848. +{
  10849. + return led_classdev_register(&pdev->dev, &wndr3700_usb_led);
  10850. +}
  10851. +
  10852. +static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev)
  10853. +{
  10854. + led_classdev_unregister(&wndr3700_usb_led);
  10855. + return 0;
  10856. +}
  10857. +
  10858. +static struct platform_driver wndr3700_usb_led_driver = {
  10859. + .probe = wndr3700_usb_led_probe,
  10860. + .remove = __devexit_p(wndr3700_usb_led_remove),
  10861. + .driver = {
  10862. + .name = DRIVER_NAME,
  10863. + .owner = THIS_MODULE,
  10864. + },
  10865. +};
  10866. +
  10867. +static int __init wndr3700_usb_led_init(void)
  10868. +{
  10869. + return platform_driver_register(&wndr3700_usb_led_driver);
  10870. +}
  10871. +
  10872. +static void __exit wndr3700_usb_led_exit(void)
  10873. +{
  10874. + platform_driver_unregister(&wndr3700_usb_led_driver);
  10875. +}
  10876. +
  10877. +module_init(wndr3700_usb_led_init);
  10878. +module_exit(wndr3700_usb_led_exit);
  10879. +
  10880. +MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700");
  10881. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  10882. +MODULE_LICENSE("GPL v2");
  10883. +MODULE_ALIAS("platform:" DRIVER_NAME);
  10884. diff -Nur linux-2.6.37.orig/drivers/mtd/maps/Kconfig linux-2.6.37/drivers/mtd/maps/Kconfig
  10885. --- linux-2.6.37.orig/drivers/mtd/maps/Kconfig 2011-01-05 01:50:19.000000000 +0100
  10886. +++ linux-2.6.37/drivers/mtd/maps/Kconfig 2011-01-11 20:25:48.000000000 +0100
  10887. @@ -260,6 +260,13 @@
  10888. Support for parsing CFE image tag and creating MTD partitions on
  10889. Broadcom BCM63xx boards.
  10890. +config MTD_AR91XX_FLASH
  10891. + tristate "Atheros AR91xx parallel flash support"
  10892. + depends on ATHEROS_AR71XX
  10893. + select MTD_COMPLEX_MAPPINGS
  10894. + help
  10895. + Parallel flash driver for the Atheros AR91xx based boards.
  10896. +
  10897. config MTD_DILNETPC
  10898. tristate "CFI Flash device mapped on DIL/Net PC"
  10899. depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
  10900. diff -Nur linux-2.6.37.orig/drivers/mtd/maps/Makefile linux-2.6.37/drivers/mtd/maps/Makefile
  10901. --- linux-2.6.37.orig/drivers/mtd/maps/Makefile 2011-01-05 01:50:19.000000000 +0100
  10902. +++ linux-2.6.37/drivers/mtd/maps/Makefile 2011-01-11 20:25:48.000000000 +0100
  10903. @@ -7,6 +7,7 @@
  10904. endif
  10905. # Chip mappings
  10906. +obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o
  10907. obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
  10908. obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
  10909. obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
  10910. diff -Nur linux-2.6.37.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.37/drivers/mtd/maps/ar91xx_flash.c
  10911. --- linux-2.6.37.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100
  10912. +++ linux-2.6.37/drivers/mtd/maps/ar91xx_flash.c 2011-01-11 20:25:48.000000000 +0100
  10913. @@ -0,0 +1,310 @@
  10914. +/*
  10915. + * Parallel flash driver for the Atheros AR91xx SoC
  10916. + *
  10917. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  10918. + *
  10919. + * This program is free software; you can redistribute it and/or modify
  10920. + * it under the terms of the GNU General Public License version 2 as
  10921. + * published by the Free Software Foundation.
  10922. + *
  10923. + */
  10924. +
  10925. +#include <linux/module.h>
  10926. +#include <linux/types.h>
  10927. +#include <linux/kernel.h>
  10928. +#include <linux/init.h>
  10929. +#include <linux/slab.h>
  10930. +#include <linux/device.h>
  10931. +#include <linux/platform_device.h>
  10932. +#include <linux/mtd/mtd.h>
  10933. +#include <linux/mtd/map.h>
  10934. +#include <linux/mtd/partitions.h>
  10935. +#include <linux/io.h>
  10936. +
  10937. +#include <asm/mach-ar71xx/ar71xx.h>
  10938. +#include <asm/mach-ar71xx/ar91xx_flash.h>
  10939. +
  10940. +#define DRV_NAME "ar91xx-flash"
  10941. +
  10942. +struct ar91xx_flash_info {
  10943. + struct mtd_info *mtd;
  10944. + struct map_info map;
  10945. +#ifdef CONFIG_MTD_PARTITIONS
  10946. + int nr_parts;
  10947. + struct mtd_partition *parts;
  10948. +#endif
  10949. +};
  10950. +
  10951. +static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs)
  10952. +{
  10953. + map_word val;
  10954. +
  10955. + if (map_bankwidth_is_1(map))
  10956. + val.x[0] = __raw_readb(map->virt + (ofs ^ 3));
  10957. + else if (map_bankwidth_is_2(map))
  10958. + val.x[0] = __raw_readw(map->virt + (ofs ^ 2));
  10959. + else
  10960. + val = map_word_ff(map);
  10961. +
  10962. + return val;
  10963. +}
  10964. +
  10965. +static void ar91xx_flash_write(struct map_info *map, map_word d,
  10966. + unsigned long ofs)
  10967. +{
  10968. + if (map_bankwidth_is_1(map))
  10969. + __raw_writeb(d.x[0], map->virt + (ofs ^ 3));
  10970. + else if (map_bankwidth_is_2(map))
  10971. + __raw_writew(d.x[0], map->virt + (ofs ^ 2));
  10972. +
  10973. + mb();
  10974. +}
  10975. +
  10976. +static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs)
  10977. +{
  10978. + map_word ret;
  10979. +
  10980. + ar71xx_flash_acquire();
  10981. + ret = ar91xx_flash_read(map, ofs);
  10982. + ar71xx_flash_release();
  10983. +
  10984. + return ret;
  10985. +}
  10986. +
  10987. +static void ar91xx_flash_write_lock(struct map_info *map, map_word d,
  10988. + unsigned long ofs)
  10989. +{
  10990. + ar71xx_flash_acquire();
  10991. + ar91xx_flash_write(map, d, ofs);
  10992. + ar71xx_flash_release();
  10993. +}
  10994. +
  10995. +static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to,
  10996. + unsigned long from, ssize_t len)
  10997. +{
  10998. + ar71xx_flash_acquire();
  10999. + inline_map_copy_from(map, to, from, len);
  11000. + ar71xx_flash_release();
  11001. +}
  11002. +
  11003. +static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to,
  11004. + const void *from, ssize_t len)
  11005. +{
  11006. + ar71xx_flash_acquire();
  11007. + inline_map_copy_to(map, to, from, len);
  11008. + ar71xx_flash_release();
  11009. +}
  11010. +
  11011. +static int ar91xx_flash_remove(struct platform_device *pdev)
  11012. +{
  11013. + struct ar91xx_flash_platform_data *pdata;
  11014. + struct ar91xx_flash_info *info;
  11015. +
  11016. + info = platform_get_drvdata(pdev);
  11017. + if (info == NULL)
  11018. + return 0;
  11019. +
  11020. + platform_set_drvdata(pdev, NULL);
  11021. +
  11022. + if (info->mtd == NULL)
  11023. + return 0;
  11024. +
  11025. + pdata = pdev->dev.platform_data;
  11026. +#ifdef CONFIG_MTD_PARTITIONS
  11027. + if (info->nr_parts) {
  11028. + del_mtd_partitions(info->mtd);
  11029. + kfree(info->parts);
  11030. + } else if (pdata->nr_parts) {
  11031. + del_mtd_partitions(info->mtd);
  11032. + } else {
  11033. + del_mtd_device(info->mtd);
  11034. + }
  11035. +#else
  11036. + del_mtd_device(info->mtd);
  11037. +#endif
  11038. + map_destroy(info->mtd);
  11039. +
  11040. + return 0;
  11041. +}
  11042. +
  11043. +static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
  11044. +#ifdef CONFIG_MTD_PARTITIONS
  11045. +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  11046. +#endif
  11047. +
  11048. +static int ar91xx_flash_probe(struct platform_device *pdev)
  11049. +{
  11050. + struct ar91xx_flash_platform_data *pdata;
  11051. + struct ar91xx_flash_info *info;
  11052. + struct resource *res;
  11053. + struct resource *region;
  11054. + const char **probe_type;
  11055. + int err = 0;
  11056. +
  11057. + pdata = pdev->dev.platform_data;
  11058. + if (pdata == NULL)
  11059. + return -EINVAL;
  11060. +
  11061. + info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info),
  11062. + GFP_KERNEL);
  11063. + if (info == NULL) {
  11064. + err = -ENOMEM;
  11065. + goto err_out;
  11066. + }
  11067. +
  11068. + platform_set_drvdata(pdev, info);
  11069. +
  11070. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  11071. + if (res == NULL) {
  11072. + err = -ENOENT;
  11073. + goto err_out;
  11074. + }
  11075. +
  11076. + dev_info(&pdev->dev, "%.8llx at %.8llx\n",
  11077. + (unsigned long long)(res->end - res->start + 1),
  11078. + (unsigned long long)res->start);
  11079. +
  11080. + region = devm_request_mem_region(&pdev->dev,
  11081. + res->start, res->end - res->start + 1,
  11082. + dev_name(&pdev->dev));
  11083. + if (region == NULL) {
  11084. + dev_err(&pdev->dev, "could not reserve memory region\n");
  11085. + err = -ENOMEM;
  11086. + goto err_out;
  11087. + }
  11088. +
  11089. + info->map.name = dev_name(&pdev->dev);
  11090. + info->map.phys = res->start;
  11091. + info->map.size = res->end - res->start + 1;
  11092. + info->map.bankwidth = pdata->width;
  11093. +
  11094. + info->map.virt = devm_ioremap(&pdev->dev, info->map.phys,
  11095. + info->map.size);
  11096. + if (info->map.virt == NULL) {
  11097. + dev_err(&pdev->dev, "failed to ioremap flash region\n");
  11098. + err = -EIO;
  11099. + goto err_out;
  11100. + }
  11101. +
  11102. + simple_map_init(&info->map);
  11103. + if (pdata->is_shared) {
  11104. + info->map.read = ar91xx_flash_read_lock;
  11105. + info->map.write = ar91xx_flash_write_lock;
  11106. + info->map.copy_from = ar91xx_flash_copy_from_lock;
  11107. + info->map.copy_to = ar91xx_flash_copy_to_lock;
  11108. + } else {
  11109. + info->map.read = ar91xx_flash_read;
  11110. + info->map.write = ar91xx_flash_write;
  11111. + }
  11112. +
  11113. + probe_type = rom_probe_types;
  11114. + for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
  11115. + info->mtd = do_map_probe(*probe_type, &info->map);
  11116. +
  11117. + if (info->mtd == NULL) {
  11118. + dev_err(&pdev->dev, "map_probe failed\n");
  11119. + err = -ENXIO;
  11120. + goto err_out;
  11121. + }
  11122. +
  11123. + info->mtd->owner = THIS_MODULE;
  11124. +
  11125. +#ifdef CONFIG_MTD_PARTITIONS
  11126. + if (pdata->nr_parts) {
  11127. + dev_info(&pdev->dev, "using static partition mapping\n");
  11128. + add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
  11129. + return 0;
  11130. + }
  11131. +
  11132. + err = parse_mtd_partitions(info->mtd, part_probe_types,
  11133. + &info->parts, 0);
  11134. + if (err > 0) {
  11135. + add_mtd_partitions(info->mtd, info->parts, err);
  11136. + return 0;
  11137. + }
  11138. +#endif
  11139. +
  11140. + add_mtd_device(info->mtd);
  11141. + return 0;
  11142. +
  11143. + err_out:
  11144. + ar91xx_flash_remove(pdev);
  11145. + return err;
  11146. +}
  11147. +
  11148. +#ifdef CONFIG_PM
  11149. +static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state)
  11150. +{
  11151. + struct ar91xx_flash_info *info = platform_get_drvdata(dev);
  11152. + int ret = 0;
  11153. +
  11154. + if (info->mtd->suspend)
  11155. + ret = info->mtd->suspend(info->mtd);
  11156. +
  11157. + if (ret)
  11158. + goto fail;
  11159. +
  11160. + return 0;
  11161. +
  11162. + fail:
  11163. + if (info->mtd->suspend) {
  11164. + BUG_ON(!info->mtd->resume);
  11165. + info->mtd->resume(info->mtd);
  11166. + }
  11167. +
  11168. + return ret;
  11169. +}
  11170. +
  11171. +static int ar91xx_flash_resume(struct platform_device *pdev)
  11172. +{
  11173. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  11174. +
  11175. + if (info->mtd->resume)
  11176. + info->mtd->resume(info->mtd);
  11177. +
  11178. + return 0;
  11179. +}
  11180. +
  11181. +static void ar91xx_flash_shutdown(struct platform_device *pdev)
  11182. +{
  11183. + struct ar91xx_flash_info *info = platform_get_drvdata(pdev);
  11184. +
  11185. + if (info->mtd->suspend && info->mtd->resume)
  11186. + if (info->mtd->suspend(info->mtd) == 0)
  11187. + info->mtd->resume(info->mtd);
  11188. +}
  11189. +#else
  11190. +#define ar91xx_flash_suspend NULL
  11191. +#define ar91xx_flash_resume NULL
  11192. +#define ar91xx_flash_shutdown NULL
  11193. +#endif
  11194. +
  11195. +static struct platform_driver ar91xx_flash_driver = {
  11196. + .probe = ar91xx_flash_probe,
  11197. + .remove = ar91xx_flash_remove,
  11198. + .suspend = ar91xx_flash_suspend,
  11199. + .resume = ar91xx_flash_resume,
  11200. + .shutdown = ar91xx_flash_shutdown,
  11201. + .driver = {
  11202. + .name = DRV_NAME,
  11203. + .owner = THIS_MODULE,
  11204. + },
  11205. +};
  11206. +
  11207. +static int __init ar91xx_flash_init(void)
  11208. +{
  11209. + return platform_driver_register(&ar91xx_flash_driver);
  11210. +}
  11211. +
  11212. +static void __exit ar91xx_flash_exit(void)
  11213. +{
  11214. + platform_driver_unregister(&ar91xx_flash_driver);
  11215. +}
  11216. +
  11217. +module_init(ar91xx_flash_init);
  11218. +module_exit(ar91xx_flash_exit);
  11219. +
  11220. +MODULE_LICENSE("GPL v2");
  11221. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11222. +MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC");
  11223. +MODULE_ALIAS("platform:" DRV_NAME);
  11224. diff -Nur linux-2.6.37.orig/drivers/mtd/nand/Kconfig linux-2.6.37/drivers/mtd/nand/Kconfig
  11225. --- linux-2.6.37.orig/drivers/mtd/nand/Kconfig 2011-01-05 01:50:19.000000000 +0100
  11226. +++ linux-2.6.37/drivers/mtd/nand/Kconfig 2011-01-11 20:25:48.000000000 +0100
  11227. @@ -532,4 +532,8 @@
  11228. Enables support for NAND Flash chips on the ST Microelectronics
  11229. Flexible Static Memory Controller (FSMC)
  11230. +config MTD_NAND_RB4XX
  11231. + tristate "NAND flash driver for RouterBoard 4xx series"
  11232. + depends on MTD_NAND && AR71XX_MACH_RB4XX
  11233. +
  11234. endif # MTD_NAND
  11235. diff -Nur linux-2.6.37.orig/drivers/mtd/nand/Makefile linux-2.6.37/drivers/mtd/nand/Makefile
  11236. --- linux-2.6.37.orig/drivers/mtd/nand/Makefile 2011-01-05 01:50:19.000000000 +0100
  11237. +++ linux-2.6.37/drivers/mtd/nand/Makefile 2011-01-11 20:25:48.000000000 +0100
  11238. @@ -33,6 +33,7 @@
  11239. obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
  11240. obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
  11241. obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
  11242. +obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
  11243. obj-$(CONFIG_MTD_ALAUDA) += alauda.o
  11244. obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
  11245. obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
  11246. diff -Nur linux-2.6.37.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.37/drivers/mtd/nand/rb4xx_nand.c
  11247. --- linux-2.6.37.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100
  11248. +++ linux-2.6.37/drivers/mtd/nand/rb4xx_nand.c 2011-01-11 20:25:48.000000000 +0100
  11249. @@ -0,0 +1,513 @@
  11250. +/*
  11251. + * NAND flash driver for the MikroTik RouterBoard 4xx series
  11252. + *
  11253. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  11254. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  11255. + *
  11256. + * This file was based on the driver for Linux 2.6.22 published by
  11257. + * MikroTik for their RouterBoard 4xx series devices.
  11258. + *
  11259. + * This program is free software; you can redistribute it and/or modify it
  11260. + * under the terms of the GNU General Public License version 2 as published
  11261. + * by the Free Software Foundation.
  11262. + */
  11263. +
  11264. +#include <linux/init.h>
  11265. +#include <linux/mtd/nand.h>
  11266. +#include <linux/mtd/mtd.h>
  11267. +#include <linux/mtd/partitions.h>
  11268. +#include <linux/platform_device.h>
  11269. +#include <linux/delay.h>
  11270. +#include <linux/io.h>
  11271. +#include <linux/gpio.h>
  11272. +#include <linux/slab.h>
  11273. +
  11274. +#include <asm/mach-ar71xx/ar71xx.h>
  11275. +
  11276. +#define DRV_NAME "rb4xx-nand"
  11277. +#define DRV_VERSION "0.1.10"
  11278. +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
  11279. +
  11280. +#define USE_FAST_READ 1
  11281. +#define USE_FAST_WRITE 1
  11282. +#undef RB4XX_NAND_DEBUG
  11283. +
  11284. +#ifdef RB4XX_NAND_DEBUG
  11285. +#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg)
  11286. +#else
  11287. +#define DBG(fmt, arg...) do {} while (0)
  11288. +#endif
  11289. +
  11290. +#define RB4XX_NAND_GPIO_RDY 5
  11291. +#define RB4XX_FLASH_HZ 33333334
  11292. +#define RB4XX_NAND_HZ 33333334
  11293. +
  11294. +#define SPI_CTRL_FASTEST 0x40
  11295. +#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */
  11296. +#define SBIT_IOC_BASE SPI_IOC_CS1
  11297. +#define SBIT_IOC_DO_SHIFT 0
  11298. +#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT)
  11299. +#define SBIT_IOC_DO2_SHIFT 18
  11300. +#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT)
  11301. +
  11302. +#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */
  11303. +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */
  11304. +#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */
  11305. +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */
  11306. +
  11307. +#define CFG_BIT_nCE 0x80
  11308. +#define CFG_BIT_CLE 0x40
  11309. +#define CFG_BIT_ALE 0x20
  11310. +#define CFG_BIT_FAN 0x10
  11311. +#define CFG_BIT_nLED4 0x08
  11312. +#define CFG_BIT_nLED3 0x04
  11313. +#define CFG_BIT_nLED2 0x02
  11314. +#define CFG_BIT_nLED1 0x01
  11315. +
  11316. +#define CFG_BIT_nLEDS \
  11317. + (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4)
  11318. +
  11319. +struct rb4xx_nand_info {
  11320. + struct nand_chip chip;
  11321. + struct mtd_info mtd;
  11322. +};
  11323. +
  11324. +/*
  11325. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11326. + * will not be able to find the kernel that we load.
  11327. + */
  11328. +static struct nand_ecclayout rb4xx_nand_ecclayout = {
  11329. + .eccbytes = 6,
  11330. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11331. + .oobavail = 9,
  11332. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11333. +};
  11334. +
  11335. +static struct mtd_partition rb4xx_nand_partitions[] = {
  11336. + {
  11337. + .name = "booter",
  11338. + .offset = 0,
  11339. + .size = (256 * 1024),
  11340. + .mask_flags = MTD_WRITEABLE,
  11341. + },
  11342. + {
  11343. + .name = "kernel",
  11344. + .offset = (256 * 1024),
  11345. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11346. + },
  11347. + {
  11348. + .name = "rootfs",
  11349. + .offset = MTDPART_OFS_NXTBLK,
  11350. + .size = (1024*1024*64) - (1024*256) - (4 * 1024 * 1024)
  11351. + },
  11352. + {
  11353. + .name = "cfgfs",
  11354. + .offset = (1024*1024*64) - (1024*256),
  11355. + .size = (1024*256),
  11356. + },
  11357. +};
  11358. +
  11359. +#if USE_FAST_READ
  11360. +#define SPI_NDATA_BASE 0x00800000
  11361. +static unsigned spi_ctrl_fread = SPI_CTRL_SAFE;
  11362. +static unsigned spi_ctrl_flash = SPI_CTRL_SAFE;
  11363. +extern unsigned mips_hpt_frequency;
  11364. +#endif
  11365. +
  11366. +static inline unsigned rb4xx_spi_rreg(unsigned r)
  11367. +{
  11368. + return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11369. +}
  11370. +
  11371. +static inline void rb4xx_spi_wreg(unsigned r, unsigned v)
  11372. +{
  11373. + __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r));
  11374. +}
  11375. +
  11376. +static inline void do_spi_clk(int bit)
  11377. +{
  11378. + unsigned bval = SBIT_IOC_BASE | (bit & 1);
  11379. +
  11380. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11381. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11382. +}
  11383. +
  11384. +static void do_spi_byte(uint8_t byte)
  11385. +{
  11386. + do_spi_clk(byte >> 7);
  11387. + do_spi_clk(byte >> 6);
  11388. + do_spi_clk(byte >> 5);
  11389. + do_spi_clk(byte >> 4);
  11390. + do_spi_clk(byte >> 3);
  11391. + do_spi_clk(byte >> 2);
  11392. + do_spi_clk(byte >> 1);
  11393. + do_spi_clk(byte);
  11394. +
  11395. + DBG("spi_byte sent 0x%02x got 0x%x\n",
  11396. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11397. +}
  11398. +
  11399. +#if USE_FAST_WRITE
  11400. +static inline void do_spi_clk_fast(int bit1, int bit2)
  11401. +{
  11402. + unsigned bval = (SBIT_IOC_BASE |
  11403. + ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) |
  11404. + ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2));
  11405. +
  11406. + rb4xx_spi_wreg(SPI_REG_IOC, bval);
  11407. + rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK);
  11408. +}
  11409. +
  11410. +static inline void do_spi_byte_fast(uint8_t byte)
  11411. +{
  11412. + do_spi_clk_fast(byte >> 7, byte >> 6);
  11413. + do_spi_clk_fast(byte >> 5, byte >> 4);
  11414. + do_spi_clk_fast(byte >> 3, byte >> 2);
  11415. + do_spi_clk_fast(byte >> 1, byte >> 0);
  11416. +
  11417. + DBG("spi_byte_fast sent 0x%02x got 0x%x\n",
  11418. + byte, rb4xx_spi_rreg(SPI_REG_RDS));
  11419. +}
  11420. +#else
  11421. +static inline void do_spi_byte_fast(uint8_t byte)
  11422. +{
  11423. + do_spi_byte(byte);
  11424. +}
  11425. +#endif /* USE_FAST_WRITE */
  11426. +
  11427. +static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData,
  11428. + unsigned recvCnt, uint8_t *recvData,
  11429. + const uint8_t *verifyData, int fastWrite)
  11430. +{
  11431. + unsigned i;
  11432. +
  11433. + DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt);
  11434. +
  11435. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11436. + rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST);
  11437. +
  11438. + do_spi_byte(cmd);
  11439. +#if 0
  11440. + if (cmd == CPLD_CMD_READ_FAST) {
  11441. + do_spi_byte(0x80);
  11442. + do_spi_byte(0);
  11443. + do_spi_byte(0);
  11444. + }
  11445. +#endif
  11446. + for (i = 0; i < sendCnt; ++i) {
  11447. + if (fastWrite)
  11448. + do_spi_byte_fast(sendData[i]);
  11449. + else
  11450. + do_spi_byte(sendData[i]);
  11451. + }
  11452. +
  11453. + for (i = 0; i < recvCnt; ++i) {
  11454. + if (fastWrite)
  11455. + do_spi_byte_fast(0);
  11456. + else
  11457. + do_spi_byte(0);
  11458. +
  11459. + if (recvData) {
  11460. + recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff;
  11461. + } else if (verifyData) {
  11462. + if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS)
  11463. + & 0xff))
  11464. + break;
  11465. + }
  11466. + }
  11467. +
  11468. + rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0);
  11469. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash);
  11470. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11471. +
  11472. + return i == recvCnt;
  11473. +}
  11474. +
  11475. +static int got_write = 1;
  11476. +
  11477. +static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt)
  11478. +{
  11479. + do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1);
  11480. + got_write = 1;
  11481. +}
  11482. +
  11483. +static void rb4xx_nand_write_byte(uint8_t byte)
  11484. +{
  11485. + rb4xx_nand_write_data(&byte, 1);
  11486. +}
  11487. +
  11488. +#if USE_FAST_READ
  11489. +static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt)
  11490. +{
  11491. + static unsigned nboffset = 0x100000;
  11492. + unsigned addr;
  11493. +
  11494. + if (got_write) {
  11495. + nboffset = (nboffset + 31) & ~31;
  11496. + if (nboffset >= 0x100000) /* 1MB */
  11497. + nboffset = 0;
  11498. +
  11499. + got_write = 0;
  11500. + rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO);
  11501. + rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread);
  11502. + rb4xx_spi_wreg(SPI_REG_FS, 0);
  11503. + }
  11504. +
  11505. + addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset;
  11506. + DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt);
  11507. +
  11508. + nboffset += cnt;
  11509. + return (uint8_t *)addr;
  11510. +}
  11511. +
  11512. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11513. +{
  11514. + unsigned size32 = cnt & ~31;
  11515. + unsigned remain = cnt & 31;
  11516. +
  11517. + if (size32) {
  11518. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11519. + memcpy(buf, (void *)addr, size32);
  11520. + }
  11521. +
  11522. + if (remain) {
  11523. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11524. + buf + size32, NULL, 0);
  11525. + }
  11526. +}
  11527. +
  11528. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11529. +{
  11530. + unsigned size32 = cnt & ~31;
  11531. + unsigned remain = cnt & 31;
  11532. +
  11533. + if (size32) {
  11534. + uint8_t *addr = rb4xx_nand_read_getaddr(size32);
  11535. + if (memcmp(buf, (void *)addr, size32) != 0)
  11536. + return 0;
  11537. + }
  11538. +
  11539. + if (remain) {
  11540. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain,
  11541. + NULL, buf + size32, 0);
  11542. + }
  11543. + return 1;
  11544. +}
  11545. +#else /* USE_FAST_READ */
  11546. +static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt)
  11547. +{
  11548. + do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0);
  11549. +}
  11550. +
  11551. +static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt)
  11552. +{
  11553. + return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0);
  11554. +}
  11555. +#endif /* USE_FAST_READ */
  11556. +
  11557. +static void rb4xx_nand_write_cfg(uint8_t byte)
  11558. +{
  11559. + do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0);
  11560. + got_write = 1;
  11561. +}
  11562. +
  11563. +static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
  11564. +{
  11565. + return gpio_get_value(RB4XX_NAND_GPIO_RDY);
  11566. +}
  11567. +
  11568. +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11569. + unsigned int ctrl)
  11570. +{
  11571. + if (ctrl & NAND_CTRL_CHANGE) {
  11572. + uint8_t cfg = CFG_BIT_nLEDS;
  11573. +
  11574. + cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0;
  11575. + cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0;
  11576. + cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE;
  11577. +
  11578. + rb4xx_nand_write_cfg(cfg);
  11579. + }
  11580. +
  11581. + if (cmd != NAND_CMD_NONE)
  11582. + rb4xx_nand_write_byte(cmd);
  11583. +}
  11584. +
  11585. +static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd)
  11586. +{
  11587. + uint8_t byte = 0;
  11588. +
  11589. + rb4xx_nand_read_data(&byte, 1);
  11590. + return byte;
  11591. +}
  11592. +
  11593. +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
  11594. + int len)
  11595. +{
  11596. + rb4xx_nand_write_data(buf, len);
  11597. +}
  11598. +
  11599. +static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf,
  11600. + int len)
  11601. +{
  11602. + rb4xx_nand_read_data(buf, len);
  11603. +}
  11604. +
  11605. +static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
  11606. + int len)
  11607. +{
  11608. + if (!rb4xx_nand_verify_data(buf, len))
  11609. + return -EFAULT;
  11610. +
  11611. + return 0;
  11612. +}
  11613. +
  11614. +static unsigned get_spi_ctrl(unsigned hz_max, const char *name)
  11615. +{
  11616. + unsigned div;
  11617. +
  11618. + div = (ar71xx_ahb_freq - 1) / (2 * hz_max);
  11619. + /*
  11620. + * CPU has a bug at (div == 0) - first bit read is random
  11621. + */
  11622. + if (div == 0)
  11623. + ++div;
  11624. +
  11625. + if (name) {
  11626. + unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000;
  11627. + unsigned div_real = 2 * (div + 1);
  11628. + printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n",
  11629. + name,
  11630. + ahb_khz / div_real,
  11631. + ahb_khz, div_real);
  11632. + }
  11633. +
  11634. + return SPI_CTRL_FASTEST + div;
  11635. +}
  11636. +
  11637. +static int __init rb4xx_nand_probe(struct platform_device *pdev)
  11638. +{
  11639. + struct rb4xx_nand_info *info;
  11640. + int ret;
  11641. +
  11642. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  11643. +
  11644. + ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY");
  11645. + if (ret) {
  11646. + printk(KERN_ERR "rb4xx-nand: gpio request failed\n");
  11647. + return ret;
  11648. + }
  11649. +
  11650. + ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY);
  11651. + if (ret) {
  11652. + printk(KERN_ERR "rb4xx-nand: unable to set input mode "
  11653. + "on gpio%d\n", RB4XX_NAND_GPIO_RDY);
  11654. + goto err_free_gpio;
  11655. + }
  11656. +
  11657. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  11658. + if (!info) {
  11659. + printk(KERN_ERR "rb4xx-nand: no memory for private data\n");
  11660. + ret = -ENOMEM;
  11661. + goto err_free_gpio;
  11662. + }
  11663. +
  11664. +#if USE_FAST_READ
  11665. + spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND");
  11666. +#endif
  11667. + spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH");
  11668. +
  11669. + rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE);
  11670. +
  11671. + info->chip.priv = &info;
  11672. + info->mtd.priv = &info->chip;
  11673. + info->mtd.owner = THIS_MODULE;
  11674. +
  11675. + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
  11676. + info->chip.dev_ready = rb4xx_nand_dev_ready;
  11677. + info->chip.read_byte = rb4xx_nand_read_byte;
  11678. + info->chip.write_buf = rb4xx_nand_write_buf;
  11679. + info->chip.read_buf = rb4xx_nand_read_buf;
  11680. + info->chip.verify_buf = rb4xx_nand_verify_buf;
  11681. +
  11682. + info->chip.chip_delay = 25;
  11683. + info->chip.ecc.mode = NAND_ECC_SOFT;
  11684. + info->chip.options |= NAND_NO_AUTOINCR;
  11685. +
  11686. + platform_set_drvdata(pdev, info);
  11687. +
  11688. + ret = nand_scan_ident(&info->mtd, 1, NULL);
  11689. + if (ret) {
  11690. + ret = -ENXIO;
  11691. + goto err_free_info;
  11692. + }
  11693. +
  11694. + if (info->mtd.writesize == 512)
  11695. + info->chip.ecc.layout = &rb4xx_nand_ecclayout;
  11696. +
  11697. + ret = nand_scan_tail(&info->mtd);
  11698. + if (ret) {
  11699. + return -ENXIO;
  11700. + goto err_set_drvdata;
  11701. + }
  11702. +
  11703. +#ifdef CONFIG_MTD_PARTITIONS
  11704. + ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions,
  11705. + ARRAY_SIZE(rb4xx_nand_partitions));
  11706. +#else
  11707. + ret = add_mtd_device(&info->mtd);
  11708. +#endif
  11709. + if (ret)
  11710. + goto err_release_nand;
  11711. +
  11712. + return 0;
  11713. +
  11714. +err_release_nand:
  11715. + nand_release(&info->mtd);
  11716. +err_set_drvdata:
  11717. + platform_set_drvdata(pdev, NULL);
  11718. +err_free_info:
  11719. + kfree(info);
  11720. +err_free_gpio:
  11721. + gpio_free(RB4XX_NAND_GPIO_RDY);
  11722. + return ret;
  11723. +}
  11724. +
  11725. +static int __devexit rb4xx_nand_remove(struct platform_device *pdev)
  11726. +{
  11727. + struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
  11728. +
  11729. + nand_release(&info->mtd);
  11730. + platform_set_drvdata(pdev, NULL);
  11731. + kfree(info);
  11732. +
  11733. + return 0;
  11734. +}
  11735. +
  11736. +static struct platform_driver rb4xx_nand_driver = {
  11737. + .probe = rb4xx_nand_probe,
  11738. + .remove = __devexit_p(rb4xx_nand_remove),
  11739. + .driver = {
  11740. + .name = DRV_NAME,
  11741. + .owner = THIS_MODULE,
  11742. + },
  11743. +};
  11744. +
  11745. +static int __init rb4xx_nand_init(void)
  11746. +{
  11747. + return platform_driver_register(&rb4xx_nand_driver);
  11748. +}
  11749. +
  11750. +static void __exit rb4xx_nand_exit(void)
  11751. +{
  11752. + platform_driver_unregister(&rb4xx_nand_driver);
  11753. +}
  11754. +
  11755. +module_init(rb4xx_nand_init);
  11756. +module_exit(rb4xx_nand_exit);
  11757. +
  11758. +MODULE_DESCRIPTION(DRV_DESC);
  11759. +MODULE_VERSION(DRV_VERSION);
  11760. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  11761. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  11762. +MODULE_LICENSE("GPL v2");
  11763. diff -Nur linux-2.6.37.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.37/drivers/mtd/nand/rb750_nand.c
  11764. --- linux-2.6.37.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100
  11765. +++ linux-2.6.37/drivers/mtd/nand/rb750_nand.c 2011-01-11 20:25:48.000000000 +0100
  11766. @@ -0,0 +1,360 @@
  11767. +/*
  11768. + * NAND flash driver for the MikroTik RouterBOARD 750
  11769. + *
  11770. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  11771. + *
  11772. + * This program is free software; you can redistribute it and/or modify it
  11773. + * under the terms of the GNU General Public License version 2 as published
  11774. + * by the Free Software Foundation.
  11775. + */
  11776. +
  11777. +#include <linux/init.h>
  11778. +#include <linux/mtd/nand.h>
  11779. +#include <linux/mtd/mtd.h>
  11780. +#include <linux/mtd/partitions.h>
  11781. +#include <linux/platform_device.h>
  11782. +#include <linux/io.h>
  11783. +
  11784. +#include <asm/mach-ar71xx/ar71xx.h>
  11785. +#include <asm/mach-ar71xx/mach-rb750.h>
  11786. +
  11787. +#define DRV_NAME "rb750-nand"
  11788. +#define DRV_VERSION "0.1.0"
  11789. +#define DRV_DESC "NAND flash driver for the RouterBOARD 750"
  11790. +
  11791. +#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0)
  11792. +#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE)
  11793. +#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE)
  11794. +#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE)
  11795. +#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE)
  11796. +#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY)
  11797. +#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE)
  11798. +
  11799. +#define RB750_NAND_DATA_SHIFT 1
  11800. +#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT)
  11801. +#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY)
  11802. +#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \
  11803. + RB750_NAND_NRE | RB750_NAND_NWE | \
  11804. + RB750_NAND_NCE)
  11805. +
  11806. +struct rb750_nand_info {
  11807. + struct nand_chip chip;
  11808. + struct mtd_info mtd;
  11809. +};
  11810. +
  11811. +/*
  11812. + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
  11813. + * will not be able to find the kernel that we load.
  11814. + */
  11815. +static struct nand_ecclayout rb750_nand_ecclayout = {
  11816. + .eccbytes = 6,
  11817. + .eccpos = { 8, 9, 10, 13, 14, 15 },
  11818. + .oobavail = 9,
  11819. + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
  11820. +};
  11821. +
  11822. +static struct mtd_partition rb750_nand_partitions[] = {
  11823. + {
  11824. + .name = "booter",
  11825. + .offset = 0,
  11826. + .size = (256 * 1024),
  11827. + .mask_flags = MTD_WRITEABLE,
  11828. + }, {
  11829. + .name = "kernel",
  11830. + .offset = (256 * 1024),
  11831. + .size = (4 * 1024 * 1024) - (256 * 1024),
  11832. + }, {
  11833. + .name = "rootfs",
  11834. + .offset = MTDPART_OFS_NXTBLK,
  11835. + .size = MTDPART_SIZ_FULL,
  11836. + },
  11837. +};
  11838. +
  11839. +static void rb750_nand_write(const u8 *buf, unsigned len)
  11840. +{
  11841. + void __iomem *base = ar71xx_gpio_base;
  11842. + u32 out;
  11843. + unsigned i;
  11844. +
  11845. + /* set data lines to output mode */
  11846. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS,
  11847. + base + GPIO_REG_OE);
  11848. +
  11849. + out = __raw_readl(base + GPIO_REG_OUT);
  11850. + out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE);
  11851. + for (i = 0; i != len; i++) {
  11852. + u32 data;
  11853. +
  11854. + data = buf[i];
  11855. + data <<= RB750_NAND_DATA_SHIFT;
  11856. + data |= out;
  11857. + __raw_writel(data, base + GPIO_REG_OUT);
  11858. +
  11859. + __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT);
  11860. + /* flush write */
  11861. + __raw_readl(base + GPIO_REG_OUT);
  11862. + }
  11863. +
  11864. + /* set data lines to input mode */
  11865. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS,
  11866. + base + GPIO_REG_OE);
  11867. + /* flush write */
  11868. + __raw_readl(base + GPIO_REG_OE);
  11869. +}
  11870. +
  11871. +static int rb750_nand_read_verify(u8 *read_buf, unsigned len,
  11872. + const u8 *verify_buf)
  11873. +{
  11874. + void __iomem *base = ar71xx_gpio_base;
  11875. + unsigned i;
  11876. +
  11877. + for (i = 0; i < len; i++) {
  11878. + u8 data;
  11879. +
  11880. + /* activate RE line */
  11881. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR);
  11882. + /* flush write */
  11883. + __raw_readl(base + GPIO_REG_CLEAR);
  11884. +
  11885. + /* read input lines */
  11886. + data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT;
  11887. +
  11888. + /* deactivate RE line */
  11889. + __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET);
  11890. +
  11891. + if (read_buf)
  11892. + read_buf[i] = data;
  11893. + else if (verify_buf && verify_buf[i] != data)
  11894. + return -EFAULT;
  11895. + }
  11896. +
  11897. + return 0;
  11898. +}
  11899. +
  11900. +static void rb750_nand_select_chip(struct mtd_info *mtd, int chip)
  11901. +{
  11902. + void __iomem *base = ar71xx_gpio_base;
  11903. + u32 func;
  11904. +
  11905. + func = __raw_readl(base + GPIO_REG_FUNC);
  11906. + if (chip >= 0) {
  11907. + /* disable latch */
  11908. + rb750_latch_change(RB750_LVC573_LE, 0);
  11909. +
  11910. + /* disable alternate functions */
  11911. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE,
  11912. + AR724X_GPIO_FUNC_SPI_EN);
  11913. +
  11914. + /* set input mode for data lines */
  11915. + __raw_writel(__raw_readl(base + GPIO_REG_OE) &
  11916. + ~RB750_NAND_INPUT_BITS,
  11917. + base + GPIO_REG_OE);
  11918. +
  11919. + /* deactivate RE and WE lines */
  11920. + __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE,
  11921. + base + GPIO_REG_SET);
  11922. + /* flush write */
  11923. + (void) __raw_readl(base + GPIO_REG_SET);
  11924. +
  11925. + /* activate CE line */
  11926. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR);
  11927. + } else {
  11928. + /* deactivate CE line */
  11929. + __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET);
  11930. + /* flush write */
  11931. + (void) __raw_readl(base + GPIO_REG_SET);
  11932. +
  11933. + __raw_writel(__raw_readl(base + GPIO_REG_OE) |
  11934. + RB750_NAND_IO0 | RB750_NAND_RDY,
  11935. + base + GPIO_REG_OE);
  11936. +
  11937. + /* restore alternate functions */
  11938. + ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN,
  11939. + AR724X_GPIO_FUNC_JTAG_DISABLE);
  11940. +
  11941. + /* enable latch */
  11942. + rb750_latch_change(0, RB750_LVC573_LE);
  11943. + }
  11944. +}
  11945. +
  11946. +static int rb750_nand_dev_ready(struct mtd_info *mtd)
  11947. +{
  11948. + void __iomem *base = ar71xx_gpio_base;
  11949. +
  11950. + return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY);
  11951. +}
  11952. +
  11953. +static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
  11954. + unsigned int ctrl)
  11955. +{
  11956. + if (ctrl & NAND_CTRL_CHANGE) {
  11957. + void __iomem *base = ar71xx_gpio_base;
  11958. + u32 t;
  11959. +
  11960. + t = __raw_readl(base + GPIO_REG_OUT);
  11961. +
  11962. + t &= ~(RB750_NAND_CLE | RB750_NAND_ALE);
  11963. + t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0;
  11964. + t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0;
  11965. +
  11966. + __raw_writel(t, base + GPIO_REG_OUT);
  11967. + /* flush write */
  11968. + __raw_readl(base + GPIO_REG_OUT);
  11969. + }
  11970. +
  11971. + if (cmd != NAND_CMD_NONE) {
  11972. + u8 t = cmd;
  11973. + rb750_nand_write(&t, 1);
  11974. + }
  11975. +}
  11976. +
  11977. +static u8 rb750_nand_read_byte(struct mtd_info *mtd)
  11978. +{
  11979. + u8 data = 0;
  11980. + rb750_nand_read_verify(&data, 1, NULL);
  11981. + return data;
  11982. +}
  11983. +
  11984. +static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
  11985. +{
  11986. + rb750_nand_read_verify(buf, len, NULL);
  11987. +}
  11988. +
  11989. +static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11990. +{
  11991. + rb750_nand_write(buf, len);
  11992. +}
  11993. +
  11994. +static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len)
  11995. +{
  11996. + return rb750_nand_read_verify(NULL, len, buf);
  11997. +}
  11998. +
  11999. +static void __init rb750_nand_gpio_init(void)
  12000. +{
  12001. + void __iomem *base = ar71xx_gpio_base;
  12002. + u32 out;
  12003. +
  12004. + out = __raw_readl(base + GPIO_REG_OUT);
  12005. +
  12006. + /* setup output levels */
  12007. + __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE,
  12008. + base + GPIO_REG_SET);
  12009. +
  12010. + __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE,
  12011. + base + GPIO_REG_CLEAR);
  12012. +
  12013. + /* setup input lines */
  12014. + __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS),
  12015. + base + GPIO_REG_OE);
  12016. +
  12017. + /* setup output lines */
  12018. + __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS,
  12019. + base + GPIO_REG_OE);
  12020. +
  12021. + rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0);
  12022. +}
  12023. +
  12024. +static int __init rb750_nand_probe(struct platform_device *pdev)
  12025. +{
  12026. + struct rb750_nand_info *info;
  12027. + int ret;
  12028. +
  12029. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  12030. +
  12031. + rb750_nand_gpio_init();
  12032. +
  12033. + info = kzalloc(sizeof(*info), GFP_KERNEL);
  12034. + if (!info)
  12035. + return -ENOMEM;
  12036. +
  12037. + info->chip.priv = &info;
  12038. + info->mtd.priv = &info->chip;
  12039. + info->mtd.owner = THIS_MODULE;
  12040. +
  12041. + info->chip.select_chip = rb750_nand_select_chip;
  12042. + info->chip.cmd_ctrl = rb750_nand_cmd_ctrl;
  12043. + info->chip.dev_ready = rb750_nand_dev_ready;
  12044. + info->chip.read_byte = rb750_nand_read_byte;
  12045. + info->chip.write_buf = rb750_nand_write_buf;
  12046. + info->chip.read_buf = rb750_nand_read_buf;
  12047. + info->chip.verify_buf = rb750_nand_verify_buf;
  12048. +
  12049. + info->chip.chip_delay = 25;
  12050. + info->chip.ecc.mode = NAND_ECC_SOFT;
  12051. + info->chip.options |= NAND_NO_AUTOINCR;
  12052. +
  12053. + platform_set_drvdata(pdev, info);
  12054. +
  12055. + ret = nand_scan_ident(&info->mtd, 1);
  12056. + if (ret) {
  12057. + ret = -ENXIO;
  12058. + goto err_free_info;
  12059. + }
  12060. +
  12061. + if (info->mtd.writesize == 512)
  12062. + info->chip.ecc.layout = &rb750_nand_ecclayout;
  12063. +
  12064. + ret = nand_scan_tail(&info->mtd);
  12065. + if (ret) {
  12066. + return -ENXIO;
  12067. + goto err_set_drvdata;
  12068. + }
  12069. +
  12070. +#ifdef CONFIG_MTD_PARTITIONS
  12071. + ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions,
  12072. + ARRAY_SIZE(rb750_nand_partitions));
  12073. +#else
  12074. + ret = add_mtd_device(&info->mtd);
  12075. +#endif
  12076. + if (ret)
  12077. + goto err_release_nand;
  12078. +
  12079. + return 0;
  12080. +
  12081. + err_release_nand:
  12082. + nand_release(&info->mtd);
  12083. + err_set_drvdata:
  12084. + platform_set_drvdata(pdev, NULL);
  12085. + err_free_info:
  12086. + kfree(info);
  12087. + return ret;
  12088. +}
  12089. +
  12090. +static int __devexit rb750_nand_remove(struct platform_device *pdev)
  12091. +{
  12092. + struct rb750_nand_info *info = platform_get_drvdata(pdev);
  12093. +
  12094. + nand_release(&info->mtd);
  12095. + platform_set_drvdata(pdev, NULL);
  12096. + kfree(info);
  12097. +
  12098. + return 0;
  12099. +}
  12100. +
  12101. +static struct platform_driver rb750_nand_driver = {
  12102. + .probe = rb750_nand_probe,
  12103. + .remove = __devexit_p(rb750_nand_remove),
  12104. + .driver = {
  12105. + .name = DRV_NAME,
  12106. + .owner = THIS_MODULE,
  12107. + },
  12108. +};
  12109. +
  12110. +static int __init rb750_nand_init(void)
  12111. +{
  12112. + return platform_driver_register(&rb750_nand_driver);
  12113. +}
  12114. +
  12115. +static void __exit rb750_nand_exit(void)
  12116. +{
  12117. + platform_driver_unregister(&rb750_nand_driver);
  12118. +}
  12119. +
  12120. +module_init(rb750_nand_init);
  12121. +module_exit(rb750_nand_exit);
  12122. +
  12123. +MODULE_DESCRIPTION(DRV_DESC);
  12124. +MODULE_VERSION(DRV_VERSION);
  12125. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  12126. +MODULE_LICENSE("GPL v2");
  12127. diff -Nur linux-2.6.37.orig/drivers/mtd/wrt160nl_part.c linux-2.6.37/drivers/mtd/wrt160nl_part.c
  12128. --- linux-2.6.37.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100
  12129. +++ linux-2.6.37/drivers/mtd/wrt160nl_part.c 2011-01-11 20:25:48.000000000 +0100
  12130. @@ -0,0 +1,181 @@
  12131. +/*
  12132. + * Copyright (C) 2009 Christian Daniel <cd@maintech.de>
  12133. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  12134. + *
  12135. + * This program is free software; you can redistribute it and/or modify
  12136. + * it under the terms of the GNU General Public License as published by
  12137. + * the Free Software Foundation; either version 2 of the License, or
  12138. + * (at your option) any later version.
  12139. + *
  12140. + * This program is distributed in the hope that it will be useful,
  12141. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12142. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12143. + * GNU General Public License for more details.
  12144. + *
  12145. + * You should have received a copy of the GNU General Public License
  12146. + * along with this program; if not, write to the Free Software
  12147. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12148. + *
  12149. + * TRX flash partition table.
  12150. + * Based on ar7 map by Felix Fietkau <nbd@openwrt.org>
  12151. + *
  12152. + */
  12153. +
  12154. +#include <linux/kernel.h>
  12155. +#include <linux/slab.h>
  12156. +#include <linux/vmalloc.h>
  12157. +
  12158. +#include <linux/mtd/mtd.h>
  12159. +#include <linux/mtd/partitions.h>
  12160. +
  12161. +struct cybertan_header {
  12162. + char magic[4];
  12163. + u8 res1[4];
  12164. + char fw_date[3];
  12165. + char fw_ver[3];
  12166. + char id[4];
  12167. + char hw_ver;
  12168. + char unused;
  12169. + u8 flags[2];
  12170. + u8 res2[10];
  12171. +};
  12172. +
  12173. +#define TRX_PARTS 6
  12174. +#define TRX_MAGIC 0x30524448
  12175. +#define TRX_MAX_OFFSET 3
  12176. +
  12177. +struct trx_header {
  12178. + uint32_t magic; /* "HDR0" */
  12179. + uint32_t len; /* Length of file including header */
  12180. + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
  12181. + uint32_t flag_version; /* 0:15 flags, 16:31 version */
  12182. + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
  12183. +};
  12184. +
  12185. +#define IH_MAGIC 0x27051956 /* Image Magic Number */
  12186. +#define IH_NMLEN 32 /* Image Name Length */
  12187. +
  12188. +struct uimage_header {
  12189. + uint32_t ih_magic; /* Image Header Magic Number */
  12190. + uint32_t ih_hcrc; /* Image Header CRC Checksum */
  12191. + uint32_t ih_time; /* Image Creation Timestamp */
  12192. + uint32_t ih_size; /* Image Data Size */
  12193. + uint32_t ih_load; /* Data» Load Address */
  12194. + uint32_t ih_ep; /* Entry Point Address */
  12195. + uint32_t ih_dcrc; /* Image Data CRC Checksum */
  12196. + uint8_t ih_os; /* Operating System */
  12197. + uint8_t ih_arch; /* CPU architecture */
  12198. + uint8_t ih_type; /* Image Type */
  12199. + uint8_t ih_comp; /* Compression Type */
  12200. + uint8_t ih_name[IH_NMLEN]; /* Image Name */
  12201. +};
  12202. +
  12203. +struct wrt160nl_header {
  12204. + struct cybertan_header cybertan;
  12205. + struct trx_header trx;
  12206. + struct uimage_header uimage;
  12207. +} __attribute__ ((packed));
  12208. +
  12209. +static struct mtd_partition trx_parts[TRX_PARTS];
  12210. +
  12211. +static int wrt160nl_parse_partitions(struct mtd_info *master,
  12212. + struct mtd_partition **pparts,
  12213. + unsigned long origin)
  12214. +{
  12215. + struct wrt160nl_header *header;
  12216. + struct trx_header *theader;
  12217. + struct uimage_header *uheader;
  12218. + size_t retlen;
  12219. + unsigned int kernel_len;
  12220. + int ret;
  12221. +
  12222. + header = vmalloc(sizeof(*header));
  12223. + if (!header) {
  12224. + return -ENOMEM;
  12225. + goto out;
  12226. + }
  12227. +
  12228. + ret = master->read(master, 4 * master->erasesize, sizeof(*header),
  12229. + &retlen, (void *) header);
  12230. + if (ret)
  12231. + goto free_hdr;
  12232. +
  12233. + if (retlen != sizeof(*header)) {
  12234. + ret = -EIO;
  12235. + goto free_hdr;
  12236. + }
  12237. +
  12238. + if (strncmp(header->cybertan.magic, "NL16", 4) != 0) {
  12239. + printk(KERN_NOTICE "%s: no WRT160NL signature found\n",
  12240. + master->name);
  12241. + goto free_hdr;
  12242. + }
  12243. +
  12244. + theader = &header->trx;
  12245. + if (le32_to_cpu(theader->magic) != TRX_MAGIC) {
  12246. + printk(KERN_NOTICE "%s: no TRX header found\n", master->name);
  12247. + goto free_hdr;
  12248. + }
  12249. +
  12250. + uheader = &header->uimage;
  12251. + if (uheader->ih_magic != IH_MAGIC) {
  12252. + printk(KERN_NOTICE "%s: no uImage found\n", master->name);
  12253. + goto free_hdr;
  12254. + }
  12255. +
  12256. + kernel_len = le32_to_cpu(theader->offsets[1]) + sizeof(struct cybertan_header);
  12257. +
  12258. + trx_parts[0].name = "u-boot";
  12259. + trx_parts[0].offset = 0;
  12260. + trx_parts[0].size = 4 * master->erasesize;
  12261. + trx_parts[0].mask_flags = MTD_WRITEABLE;
  12262. +
  12263. + trx_parts[1].name = "kernel";
  12264. + trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size;
  12265. + trx_parts[1].size = kernel_len;
  12266. + trx_parts[1].mask_flags = 0;
  12267. +
  12268. + trx_parts[2].name = "rootfs";
  12269. + trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size;
  12270. + trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size;
  12271. + trx_parts[2].mask_flags = 0;
  12272. +
  12273. + trx_parts[3].name = "nvram";
  12274. + trx_parts[3].offset = master->size - 2 * master->erasesize;
  12275. + trx_parts[3].size = master->erasesize;
  12276. + trx_parts[3].mask_flags = MTD_WRITEABLE;
  12277. +
  12278. + trx_parts[4].name = "art";
  12279. + trx_parts[4].offset = master->size - master->erasesize;
  12280. + trx_parts[4].size = master->erasesize;
  12281. + trx_parts[4].mask_flags = MTD_WRITEABLE;
  12282. +
  12283. + trx_parts[5].name = "firmware";
  12284. + trx_parts[5].offset = 4 * master->erasesize;
  12285. + trx_parts[5].size = master->size - 6 * master->erasesize;
  12286. + trx_parts[5].mask_flags = 0;
  12287. +
  12288. + *pparts = trx_parts;
  12289. + ret = TRX_PARTS;
  12290. +
  12291. + free_hdr:
  12292. + vfree(header);
  12293. + out:
  12294. + return ret;
  12295. +}
  12296. +
  12297. +static struct mtd_part_parser wrt160nl_parser = {
  12298. + .owner = THIS_MODULE,
  12299. + .parse_fn = wrt160nl_parse_partitions,
  12300. + .name = "wrt160nl",
  12301. +};
  12302. +
  12303. +static int __init wrt160nl_parser_init(void)
  12304. +{
  12305. + return register_mtd_parser(&wrt160nl_parser);
  12306. +}
  12307. +
  12308. +module_init(wrt160nl_parser_init);
  12309. +
  12310. +MODULE_LICENSE("GPL");
  12311. +MODULE_AUTHOR("Christian Daniel <cd@maintech.de>");
  12312. diff -Nur linux-2.6.37.orig/drivers/net/Kconfig linux-2.6.37/drivers/net/Kconfig
  12313. --- linux-2.6.37.orig/drivers/net/Kconfig 2011-01-05 01:50:19.000000000 +0100
  12314. +++ linux-2.6.37/drivers/net/Kconfig 2011-01-11 20:25:48.000000000 +0100
  12315. @@ -2068,6 +2068,8 @@
  12316. The safe and default value for this is N.
  12317. +source drivers/net/ag71xx/Kconfig
  12318. +
  12319. config DL2K
  12320. tristate "DL2000/TC902x-based Gigabit Ethernet support"
  12321. depends on PCI
  12322. diff -Nur linux-2.6.37.orig/drivers/net/Makefile linux-2.6.37/drivers/net/Makefile
  12323. --- linux-2.6.37.orig/drivers/net/Makefile 2011-01-05 01:50:19.000000000 +0100
  12324. +++ linux-2.6.37/drivers/net/Makefile 2011-01-11 20:25:48.000000000 +0100
  12325. @@ -112,6 +112,7 @@
  12326. # end link order section
  12327. #
  12328. +obj-$(CONFIG_AG71XX) += ag71xx/
  12329. obj-$(CONFIG_SUNDANCE) += sundance.o
  12330. obj-$(CONFIG_HAMACHI) += hamachi.o
  12331. obj-$(CONFIG_NET) += Space.o loopback.o
  12332. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/Kconfig linux-2.6.37/drivers/net/ag71xx/Kconfig
  12333. --- linux-2.6.37.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100
  12334. +++ linux-2.6.37/drivers/net/ag71xx/Kconfig 2011-01-11 20:25:48.000000000 +0100
  12335. @@ -0,0 +1,33 @@
  12336. +config AG71XX
  12337. + tristate "Atheros AR71xx built-in ethernet mac support"
  12338. + depends on ATHEROS_AR71XX
  12339. + select PHYLIB
  12340. + help
  12341. + If you wish to compile a kernel for AR71xx/91xx and enable
  12342. + ethernet support, then you should always answer Y to this.
  12343. +
  12344. +if AG71XX
  12345. +
  12346. +config AG71XX_DEBUG
  12347. + bool "Atheros AR71xx built-in ethernet driver debugging"
  12348. + default n
  12349. + help
  12350. + Atheros AR71xx built-in ethernet driver debugging messages.
  12351. +
  12352. +config AG71XX_DEBUG_FS
  12353. + bool "Atheros AR71xx built-in ethernet driver debugfs support"
  12354. + depends on DEBUG_FS
  12355. + default n
  12356. + help
  12357. + Say Y, if you need access to various statistics provided by
  12358. + the ag71xx driver.
  12359. +
  12360. +config AG71XX_AR8216_SUPPORT
  12361. + bool "special support for the Atheros AR8216 switch"
  12362. + default n
  12363. + default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU
  12364. + help
  12365. + Say 'y' here if you want to enable special support for the
  12366. + Atheros AR8216 switch found on some boards.
  12367. +
  12368. +endif
  12369. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/Makefile linux-2.6.37/drivers/net/ag71xx/Makefile
  12370. --- linux-2.6.37.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  12371. +++ linux-2.6.37/drivers/net/ag71xx/Makefile 2011-01-11 20:25:48.000000000 +0100
  12372. @@ -0,0 +1,14 @@
  12373. +#
  12374. +# Makefile for the Atheros AR71xx built-in ethernet macs
  12375. +#
  12376. +
  12377. +ag71xx-y += ag71xx_main.o
  12378. +ag71xx-y += ag71xx_ethtool.o
  12379. +ag71xx-y += ag71xx_phy.o
  12380. +ag71xx-y += ag71xx_mdio.o
  12381. +
  12382. +ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o
  12383. +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o
  12384. +
  12385. +obj-$(CONFIG_AG71XX) += ag71xx.o
  12386. +
  12387. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.37/drivers/net/ag71xx/ag71xx.h
  12388. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100
  12389. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx.h 2011-01-11 20:25:48.000000000 +0100
  12390. @@ -0,0 +1,500 @@
  12391. +/*
  12392. + * Atheros AR71xx built-in ethernet mac driver
  12393. + *
  12394. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12395. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12396. + *
  12397. + * Based on Atheros' AG7100 driver
  12398. + *
  12399. + * This program is free software; you can redistribute it and/or modify it
  12400. + * under the terms of the GNU General Public License version 2 as published
  12401. + * by the Free Software Foundation.
  12402. + */
  12403. +
  12404. +#ifndef __AG71XX_H
  12405. +#define __AG71XX_H
  12406. +
  12407. +#include <linux/kernel.h>
  12408. +#include <linux/version.h>
  12409. +#include <linux/module.h>
  12410. +#include <linux/init.h>
  12411. +#include <linux/types.h>
  12412. +#include <linux/random.h>
  12413. +#include <linux/spinlock.h>
  12414. +#include <linux/interrupt.h>
  12415. +#include <linux/platform_device.h>
  12416. +#include <linux/ethtool.h>
  12417. +#include <linux/etherdevice.h>
  12418. +#include <linux/phy.h>
  12419. +#include <linux/skbuff.h>
  12420. +#include <linux/dma-mapping.h>
  12421. +#include <linux/workqueue.h>
  12422. +
  12423. +#include <linux/bitops.h>
  12424. +
  12425. +#include <asm/mach-ar71xx/ar71xx.h>
  12426. +#include <asm/mach-ar71xx/platform.h>
  12427. +
  12428. +#define ETH_FCS_LEN 4
  12429. +
  12430. +#define AG71XX_DRV_NAME "ag71xx"
  12431. +#define AG71XX_DRV_VERSION "0.5.35"
  12432. +
  12433. +#define AG71XX_NAPI_WEIGHT 64
  12434. +#define AG71XX_OOM_REFILL (1 + HZ/10)
  12435. +
  12436. +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
  12437. +#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
  12438. +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
  12439. +
  12440. +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
  12441. +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
  12442. +
  12443. +#define AG71XX_TX_FIFO_LEN 2048
  12444. +#define AG71XX_TX_MTU_LEN 1536
  12445. +#define AG71XX_RX_PKT_RESERVE 64
  12446. +#define AG71XX_RX_PKT_SIZE \
  12447. + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
  12448. +
  12449. +#define AG71XX_TX_RING_SIZE 64
  12450. +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
  12451. +#define AG71XX_TX_THRES_WAKEUP \
  12452. + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
  12453. +
  12454. +#define AG71XX_RX_RING_SIZE 128
  12455. +
  12456. +#ifdef CONFIG_AG71XX_DEBUG
  12457. +#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args)
  12458. +#else
  12459. +#define DBG(fmt, args...) do {} while (0)
  12460. +#endif
  12461. +
  12462. +#define ag71xx_assert(_cond) \
  12463. +do { \
  12464. + if (_cond) \
  12465. + break; \
  12466. + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \
  12467. + BUG(); \
  12468. +} while (0)
  12469. +
  12470. +struct ag71xx_desc {
  12471. + u32 data;
  12472. + u32 ctrl;
  12473. +#define DESC_EMPTY BIT(31)
  12474. +#define DESC_MORE BIT(24)
  12475. +#define DESC_PKTLEN_M 0xfff
  12476. + u32 next;
  12477. + u32 pad;
  12478. +} __attribute__((aligned(4)));
  12479. +
  12480. +struct ag71xx_buf {
  12481. + struct sk_buff *skb;
  12482. + struct ag71xx_desc *desc;
  12483. + dma_addr_t dma_addr;
  12484. + u32 pad;
  12485. +};
  12486. +
  12487. +struct ag71xx_ring {
  12488. + struct ag71xx_buf *buf;
  12489. + u8 *descs_cpu;
  12490. + dma_addr_t descs_dma;
  12491. + unsigned int desc_size;
  12492. + unsigned int curr;
  12493. + unsigned int dirty;
  12494. + unsigned int size;
  12495. +};
  12496. +
  12497. +struct ag71xx_mdio {
  12498. + struct mii_bus *mii_bus;
  12499. + int mii_irq[PHY_MAX_ADDR];
  12500. + void __iomem *mdio_base;
  12501. + struct ag71xx_mdio_platform_data *pdata;
  12502. +};
  12503. +
  12504. +struct ag71xx_int_stats {
  12505. + unsigned long rx_pr;
  12506. + unsigned long rx_be;
  12507. + unsigned long rx_of;
  12508. + unsigned long tx_ps;
  12509. + unsigned long tx_be;
  12510. + unsigned long tx_ur;
  12511. + unsigned long total;
  12512. +};
  12513. +
  12514. +struct ag71xx_napi_stats {
  12515. + unsigned long napi_calls;
  12516. + unsigned long rx_count;
  12517. + unsigned long rx_packets;
  12518. + unsigned long rx_packets_max;
  12519. + unsigned long tx_count;
  12520. + unsigned long tx_packets;
  12521. + unsigned long tx_packets_max;
  12522. +
  12523. + unsigned long rx[AG71XX_NAPI_WEIGHT + 1];
  12524. + unsigned long tx[AG71XX_NAPI_WEIGHT + 1];
  12525. +};
  12526. +
  12527. +struct ag71xx_debug {
  12528. + struct dentry *debugfs_dir;
  12529. + struct dentry *debugfs_int_stats;
  12530. + struct dentry *debugfs_napi_stats;
  12531. +
  12532. + struct ag71xx_int_stats int_stats;
  12533. + struct ag71xx_napi_stats napi_stats;
  12534. +};
  12535. +
  12536. +struct ag71xx {
  12537. + void __iomem *mac_base;
  12538. + void __iomem *mii_ctrl;
  12539. +
  12540. + spinlock_t lock;
  12541. + struct platform_device *pdev;
  12542. + struct net_device *dev;
  12543. + struct napi_struct napi;
  12544. + u32 msg_enable;
  12545. +
  12546. + struct ag71xx_ring rx_ring;
  12547. + struct ag71xx_ring tx_ring;
  12548. +
  12549. + struct mii_bus *mii_bus;
  12550. + struct phy_device *phy_dev;
  12551. +
  12552. + unsigned int link;
  12553. + unsigned int speed;
  12554. + int duplex;
  12555. +
  12556. + struct work_struct restart_work;
  12557. + struct timer_list oom_timer;
  12558. +
  12559. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12560. + struct ag71xx_debug debug;
  12561. +#endif
  12562. +};
  12563. +
  12564. +extern struct ethtool_ops ag71xx_ethtool_ops;
  12565. +void ag71xx_link_adjust(struct ag71xx *ag);
  12566. +
  12567. +int ag71xx_mdio_driver_init(void) __init;
  12568. +void ag71xx_mdio_driver_exit(void);
  12569. +
  12570. +int ag71xx_phy_connect(struct ag71xx *ag);
  12571. +void ag71xx_phy_disconnect(struct ag71xx *ag);
  12572. +void ag71xx_phy_start(struct ag71xx *ag);
  12573. +void ag71xx_phy_stop(struct ag71xx *ag);
  12574. +
  12575. +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
  12576. +{
  12577. + return ag->pdev->dev.platform_data;
  12578. +}
  12579. +
  12580. +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
  12581. +{
  12582. + return ((desc->ctrl & DESC_EMPTY) != 0);
  12583. +}
  12584. +
  12585. +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
  12586. +{
  12587. + return (desc->ctrl & DESC_PKTLEN_M);
  12588. +}
  12589. +
  12590. +/* Register offsets */
  12591. +#define AG71XX_REG_MAC_CFG1 0x0000
  12592. +#define AG71XX_REG_MAC_CFG2 0x0004
  12593. +#define AG71XX_REG_MAC_IPG 0x0008
  12594. +#define AG71XX_REG_MAC_HDX 0x000c
  12595. +#define AG71XX_REG_MAC_MFL 0x0010
  12596. +#define AG71XX_REG_MII_CFG 0x0020
  12597. +#define AG71XX_REG_MII_CMD 0x0024
  12598. +#define AG71XX_REG_MII_ADDR 0x0028
  12599. +#define AG71XX_REG_MII_CTRL 0x002c
  12600. +#define AG71XX_REG_MII_STATUS 0x0030
  12601. +#define AG71XX_REG_MII_IND 0x0034
  12602. +#define AG71XX_REG_MAC_IFCTL 0x0038
  12603. +#define AG71XX_REG_MAC_ADDR1 0x0040
  12604. +#define AG71XX_REG_MAC_ADDR2 0x0044
  12605. +#define AG71XX_REG_FIFO_CFG0 0x0048
  12606. +#define AG71XX_REG_FIFO_CFG1 0x004c
  12607. +#define AG71XX_REG_FIFO_CFG2 0x0050
  12608. +#define AG71XX_REG_FIFO_CFG3 0x0054
  12609. +#define AG71XX_REG_FIFO_CFG4 0x0058
  12610. +#define AG71XX_REG_FIFO_CFG5 0x005c
  12611. +#define AG71XX_REG_FIFO_RAM0 0x0060
  12612. +#define AG71XX_REG_FIFO_RAM1 0x0064
  12613. +#define AG71XX_REG_FIFO_RAM2 0x0068
  12614. +#define AG71XX_REG_FIFO_RAM3 0x006c
  12615. +#define AG71XX_REG_FIFO_RAM4 0x0070
  12616. +#define AG71XX_REG_FIFO_RAM5 0x0074
  12617. +#define AG71XX_REG_FIFO_RAM6 0x0078
  12618. +#define AG71XX_REG_FIFO_RAM7 0x007c
  12619. +
  12620. +#define AG71XX_REG_TX_CTRL 0x0180
  12621. +#define AG71XX_REG_TX_DESC 0x0184
  12622. +#define AG71XX_REG_TX_STATUS 0x0188
  12623. +#define AG71XX_REG_RX_CTRL 0x018c
  12624. +#define AG71XX_REG_RX_DESC 0x0190
  12625. +#define AG71XX_REG_RX_STATUS 0x0194
  12626. +#define AG71XX_REG_INT_ENABLE 0x0198
  12627. +#define AG71XX_REG_INT_STATUS 0x019c
  12628. +
  12629. +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
  12630. +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
  12631. +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
  12632. +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
  12633. +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
  12634. +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
  12635. +#define MAC_CFG1_LB BIT(8) /* Loopback mode */
  12636. +#define MAC_CFG1_SR BIT(31) /* Soft Reset */
  12637. +
  12638. +#define MAC_CFG2_FDX BIT(0)
  12639. +#define MAC_CFG2_CRC_EN BIT(1)
  12640. +#define MAC_CFG2_PAD_CRC_EN BIT(2)
  12641. +#define MAC_CFG2_LEN_CHECK BIT(4)
  12642. +#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
  12643. +#define MAC_CFG2_IF_1000 BIT(9)
  12644. +#define MAC_CFG2_IF_10_100 BIT(8)
  12645. +
  12646. +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
  12647. +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
  12648. +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
  12649. +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
  12650. +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
  12651. +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
  12652. + | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
  12653. +
  12654. +#define FIFO_CFG0_ENABLE_SHIFT 8
  12655. +
  12656. +#define FIFO_CFG4_DE BIT(0) /* Drop Event */
  12657. +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
  12658. +#define FIFO_CFG4_FC BIT(2) /* False Carrier */
  12659. +#define FIFO_CFG4_CE BIT(3) /* Code Error */
  12660. +#define FIFO_CFG4_CR BIT(4) /* CRC error */
  12661. +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
  12662. +#define FIFO_CFG4_LO BIT(6) /* Length out of range */
  12663. +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
  12664. +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
  12665. +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
  12666. +#define FIFO_CFG4_DR BIT(10) /* Dribble */
  12667. +#define FIFO_CFG4_LE BIT(11) /* Long Event */
  12668. +#define FIFO_CFG4_CF BIT(12) /* Control Frame */
  12669. +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
  12670. +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
  12671. +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
  12672. +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
  12673. +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
  12674. +
  12675. +#define FIFO_CFG5_DE BIT(0) /* Drop Event */
  12676. +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
  12677. +#define FIFO_CFG5_FC BIT(2) /* False Carrier */
  12678. +#define FIFO_CFG5_CE BIT(3) /* Code Error */
  12679. +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
  12680. +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
  12681. +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
  12682. +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
  12683. +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
  12684. +#define FIFO_CFG5_DR BIT(9) /* Dribble */
  12685. +#define FIFO_CFG5_CF BIT(10) /* Control Frame */
  12686. +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
  12687. +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
  12688. +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
  12689. +#define FIFO_CFG5_LE BIT(14) /* Long Event */
  12690. +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
  12691. +#define FIFO_CFG5_16 BIT(16) /* unknown */
  12692. +#define FIFO_CFG5_17 BIT(17) /* unknown */
  12693. +#define FIFO_CFG5_SF BIT(18) /* Short Frame */
  12694. +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
  12695. +
  12696. +#define AG71XX_INT_TX_PS BIT(0)
  12697. +#define AG71XX_INT_TX_UR BIT(1)
  12698. +#define AG71XX_INT_TX_BE BIT(3)
  12699. +#define AG71XX_INT_RX_PR BIT(4)
  12700. +#define AG71XX_INT_RX_OF BIT(6)
  12701. +#define AG71XX_INT_RX_BE BIT(7)
  12702. +
  12703. +#define MAC_IFCTL_SPEED BIT(16)
  12704. +
  12705. +#define MII_CFG_CLK_DIV_4 0
  12706. +#define MII_CFG_CLK_DIV_6 2
  12707. +#define MII_CFG_CLK_DIV_8 3
  12708. +#define MII_CFG_CLK_DIV_10 4
  12709. +#define MII_CFG_CLK_DIV_14 5
  12710. +#define MII_CFG_CLK_DIV_20 6
  12711. +#define MII_CFG_CLK_DIV_28 7
  12712. +#define MII_CFG_RESET BIT(31)
  12713. +
  12714. +#define MII_CMD_WRITE 0x0
  12715. +#define MII_CMD_READ 0x1
  12716. +#define MII_ADDR_SHIFT 8
  12717. +#define MII_IND_BUSY BIT(0)
  12718. +#define MII_IND_INVALID BIT(2)
  12719. +
  12720. +#define TX_CTRL_TXE BIT(0) /* Tx Enable */
  12721. +
  12722. +#define TX_STATUS_PS BIT(0) /* Packet Sent */
  12723. +#define TX_STATUS_UR BIT(1) /* Tx Underrun */
  12724. +#define TX_STATUS_BE BIT(3) /* Bus Error */
  12725. +
  12726. +#define RX_CTRL_RXE BIT(0) /* Rx Enable */
  12727. +
  12728. +#define RX_STATUS_PR BIT(0) /* Packet Received */
  12729. +#define RX_STATUS_OF BIT(2) /* Rx Overflow */
  12730. +#define RX_STATUS_BE BIT(3) /* Bus Error */
  12731. +
  12732. +#define MII_CTRL_IF_MASK 3
  12733. +#define MII_CTRL_SPEED_SHIFT 4
  12734. +#define MII_CTRL_SPEED_MASK 3
  12735. +#define MII_CTRL_SPEED_10 0
  12736. +#define MII_CTRL_SPEED_100 1
  12737. +#define MII_CTRL_SPEED_1000 2
  12738. +
  12739. +static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)
  12740. +{
  12741. + switch (reg) {
  12742. + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL:
  12743. + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS:
  12744. + break;
  12745. +
  12746. + default:
  12747. + BUG();
  12748. + }
  12749. +}
  12750. +
  12751. +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
  12752. +{
  12753. + ag71xx_check_reg_offset(ag, reg);
  12754. +
  12755. + __raw_writel(value, ag->mac_base + reg);
  12756. + /* flush write */
  12757. + (void) __raw_readl(ag->mac_base + reg);
  12758. +}
  12759. +
  12760. +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
  12761. +{
  12762. + ag71xx_check_reg_offset(ag, reg);
  12763. +
  12764. + return __raw_readl(ag->mac_base + reg);
  12765. +}
  12766. +
  12767. +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
  12768. +{
  12769. + void __iomem *r;
  12770. +
  12771. + ag71xx_check_reg_offset(ag, reg);
  12772. +
  12773. + r = ag->mac_base + reg;
  12774. + __raw_writel(__raw_readl(r) | mask, r);
  12775. + /* flush write */
  12776. + (void)__raw_readl(r);
  12777. +}
  12778. +
  12779. +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
  12780. +{
  12781. + void __iomem *r;
  12782. +
  12783. + ag71xx_check_reg_offset(ag, reg);
  12784. +
  12785. + r = ag->mac_base + reg;
  12786. + __raw_writel(__raw_readl(r) & ~mask, r);
  12787. + /* flush write */
  12788. + (void) __raw_readl(r);
  12789. +}
  12790. +
  12791. +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
  12792. +{
  12793. + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
  12794. +}
  12795. +
  12796. +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
  12797. +{
  12798. + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
  12799. +}
  12800. +
  12801. +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
  12802. +{
  12803. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12804. +
  12805. + if (pdata->is_ar724x)
  12806. + return;
  12807. +
  12808. + __raw_writel(value, ag->mii_ctrl);
  12809. +
  12810. + /* flush write */
  12811. + __raw_readl(ag->mii_ctrl);
  12812. +}
  12813. +
  12814. +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
  12815. +{
  12816. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  12817. +
  12818. + if (pdata->is_ar724x)
  12819. + return 0xffffffff;
  12820. +
  12821. + return __raw_readl(ag->mii_ctrl);
  12822. +}
  12823. +
  12824. +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
  12825. + unsigned int mii_if)
  12826. +{
  12827. + u32 t;
  12828. +
  12829. + t = ag71xx_mii_ctrl_rr(ag);
  12830. + t &= ~(MII_CTRL_IF_MASK);
  12831. + t |= (mii_if & MII_CTRL_IF_MASK);
  12832. + ag71xx_mii_ctrl_wr(ag, t);
  12833. +}
  12834. +
  12835. +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
  12836. + unsigned int speed)
  12837. +{
  12838. + u32 t;
  12839. +
  12840. + t = ag71xx_mii_ctrl_rr(ag);
  12841. + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
  12842. + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
  12843. + ag71xx_mii_ctrl_wr(ag, t);
  12844. +}
  12845. +
  12846. +#ifdef CONFIG_AG71XX_AR8216_SUPPORT
  12847. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
  12848. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12849. + int pktlen);
  12850. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12851. +{
  12852. + return ag71xx_get_pdata(ag)->has_ar8216;
  12853. +}
  12854. +#else
  12855. +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
  12856. + struct sk_buff *skb)
  12857. +{
  12858. +}
  12859. +
  12860. +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
  12861. + struct sk_buff *skb,
  12862. + int pktlen)
  12863. +{
  12864. + return 0;
  12865. +}
  12866. +static inline int ag71xx_has_ar8216(struct ag71xx *ag)
  12867. +{
  12868. + return 0;
  12869. +}
  12870. +#endif
  12871. +
  12872. +#ifdef CONFIG_AG71XX_DEBUG_FS
  12873. +int ag71xx_debugfs_root_init(void);
  12874. +void ag71xx_debugfs_root_exit(void);
  12875. +int ag71xx_debugfs_init(struct ag71xx *ag);
  12876. +void ag71xx_debugfs_exit(struct ag71xx *ag);
  12877. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status);
  12878. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx);
  12879. +#else
  12880. +static inline int ag71xx_debugfs_root_init(void) { return 0; }
  12881. +static inline void ag71xx_debugfs_root_exit(void) {}
  12882. +static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; }
  12883. +static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {}
  12884. +static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag,
  12885. + u32 status) {}
  12886. +static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag,
  12887. + int rx, int tx) {}
  12888. +#endif /* CONFIG_AG71XX_DEBUG_FS */
  12889. +
  12890. +#endif /* _AG71XX_H */
  12891. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.37/drivers/net/ag71xx/ag71xx_ar8216.c
  12892. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100
  12893. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_ar8216.c 2011-01-11 20:25:48.000000000 +0100
  12894. @@ -0,0 +1,44 @@
  12895. +/*
  12896. + * Atheros AR71xx built-in ethernet mac driver
  12897. + * Special support for the Atheros ar8216 switch chip
  12898. + *
  12899. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  12900. + *
  12901. + * Based on Atheros' AG7100 driver
  12902. + *
  12903. + * This program is free software; you can redistribute it and/or modify it
  12904. + * under the terms of the GNU General Public License version 2 as published
  12905. + * by the Free Software Foundation.
  12906. + */
  12907. +
  12908. +#include "ag71xx.h"
  12909. +
  12910. +#define AR8216_PACKET_TYPE_MASK 0xf
  12911. +#define AR8216_PACKET_TYPE_NORMAL 0
  12912. +
  12913. +#define AR8216_HEADER_LEN 2
  12914. +
  12915. +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
  12916. +{
  12917. + skb_push(skb, AR8216_HEADER_LEN);
  12918. + skb->data[0] = 0x10;
  12919. + skb->data[1] = 0x80;
  12920. +}
  12921. +
  12922. +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
  12923. + int pktlen)
  12924. +{
  12925. + u8 type;
  12926. +
  12927. + type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
  12928. + switch (type) {
  12929. + case AR8216_PACKET_TYPE_NORMAL:
  12930. + break;
  12931. +
  12932. + default:
  12933. + return -EINVAL;
  12934. + }
  12935. +
  12936. + skb_pull(skb, AR8216_HEADER_LEN);
  12937. + return 0;
  12938. +}
  12939. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.37/drivers/net/ag71xx/ag71xx_debugfs.c
  12940. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  12941. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_debugfs.c 2011-01-11 20:25:48.000000000 +0100
  12942. @@ -0,0 +1,197 @@
  12943. +/*
  12944. + * Atheros AR71xx built-in ethernet mac driver
  12945. + *
  12946. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  12947. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  12948. + *
  12949. + * Based on Atheros' AG7100 driver
  12950. + *
  12951. + * This program is free software; you can redistribute it and/or modify it
  12952. + * under the terms of the GNU General Public License version 2 as published
  12953. + * by the Free Software Foundation.
  12954. + */
  12955. +
  12956. +#include <linux/debugfs.h>
  12957. +
  12958. +#include "ag71xx.h"
  12959. +
  12960. +static struct dentry *ag71xx_debugfs_root;
  12961. +
  12962. +static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file)
  12963. +{
  12964. + file->private_data = inode->i_private;
  12965. + return 0;
  12966. +}
  12967. +
  12968. +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status)
  12969. +{
  12970. + if (status)
  12971. + ag->debug.int_stats.total++;
  12972. + if (status & AG71XX_INT_TX_PS)
  12973. + ag->debug.int_stats.tx_ps++;
  12974. + if (status & AG71XX_INT_TX_UR)
  12975. + ag->debug.int_stats.tx_ur++;
  12976. + if (status & AG71XX_INT_TX_BE)
  12977. + ag->debug.int_stats.tx_be++;
  12978. + if (status & AG71XX_INT_RX_PR)
  12979. + ag->debug.int_stats.rx_pr++;
  12980. + if (status & AG71XX_INT_RX_OF)
  12981. + ag->debug.int_stats.rx_of++;
  12982. + if (status & AG71XX_INT_RX_BE)
  12983. + ag->debug.int_stats.rx_be++;
  12984. +}
  12985. +
  12986. +static ssize_t read_file_int_stats(struct file *file, char __user *user_buf,
  12987. + size_t count, loff_t *ppos)
  12988. +{
  12989. +#define PR_INT_STAT(_label, _field) \
  12990. + len += snprintf(buf + len, sizeof(buf) - len, \
  12991. + "%20s: %10lu\n", _label, ag->debug.int_stats._field);
  12992. +
  12993. + struct ag71xx *ag = file->private_data;
  12994. + char buf[256];
  12995. + unsigned int len = 0;
  12996. +
  12997. + PR_INT_STAT("TX Packet Sent", tx_ps);
  12998. + PR_INT_STAT("TX Underrun", tx_ur);
  12999. + PR_INT_STAT("TX Bus Error", tx_be);
  13000. + PR_INT_STAT("RX Packet Received", rx_pr);
  13001. + PR_INT_STAT("RX Overflow", rx_of);
  13002. + PR_INT_STAT("RX Bus Error", rx_be);
  13003. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  13004. + PR_INT_STAT("Total", total);
  13005. +
  13006. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  13007. +#undef PR_INT_STAT
  13008. +}
  13009. +
  13010. +static const struct file_operations ag71xx_fops_int_stats = {
  13011. + .open = ag71xx_debugfs_generic_open,
  13012. + .read = read_file_int_stats,
  13013. + .owner = THIS_MODULE
  13014. +};
  13015. +
  13016. +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
  13017. +{
  13018. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  13019. +
  13020. + if (rx) {
  13021. + stats->rx_count++;
  13022. + stats->rx_packets += rx;
  13023. + if (rx <= AG71XX_NAPI_WEIGHT)
  13024. + stats->rx[rx]++;
  13025. + if (rx > stats->rx_packets_max)
  13026. + stats->rx_packets_max = rx;
  13027. + }
  13028. +
  13029. + if (tx) {
  13030. + stats->tx_count++;
  13031. + stats->tx_packets += tx;
  13032. + if (tx <= AG71XX_NAPI_WEIGHT)
  13033. + stats->tx[tx]++;
  13034. + if (tx > stats->tx_packets_max)
  13035. + stats->tx_packets_max = tx;
  13036. + }
  13037. +}
  13038. +
  13039. +static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf,
  13040. + size_t count, loff_t *ppos)
  13041. +{
  13042. + struct ag71xx *ag = file->private_data;
  13043. + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats;
  13044. + char buf[2048];
  13045. + unsigned int len = 0;
  13046. + unsigned long rx_avg = 0;
  13047. + unsigned long tx_avg = 0;
  13048. + int i;
  13049. +
  13050. + if (stats->rx_count)
  13051. + rx_avg = stats->rx_packets / stats->rx_count;
  13052. +
  13053. + if (stats->tx_count)
  13054. + tx_avg = stats->tx_packets / stats->tx_count;
  13055. +
  13056. + len += snprintf(buf + len, sizeof(buf) - len, "%3s %10s %10s\n",
  13057. + "len", "rx", "tx");
  13058. +
  13059. + for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++)
  13060. + len += snprintf(buf + len, sizeof(buf) - len,
  13061. + "%3d: %10lu %10lu\n",
  13062. + i, stats->rx[i], stats->tx[i]);
  13063. +
  13064. + len += snprintf(buf + len, sizeof(buf) - len, "\n");
  13065. +
  13066. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13067. + "sum", stats->rx_count, stats->tx_count);
  13068. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13069. + "avg", rx_avg, tx_avg);
  13070. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13071. + "max", stats->rx_packets_max, stats->tx_packets_max);
  13072. + len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n",
  13073. + "pkt", stats->rx_packets, stats->tx_packets);
  13074. +
  13075. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  13076. +}
  13077. +
  13078. +static const struct file_operations ag71xx_fops_napi_stats = {
  13079. + .open = ag71xx_debugfs_generic_open,
  13080. + .read = read_file_napi_stats,
  13081. + .owner = THIS_MODULE
  13082. +};
  13083. +
  13084. +void ag71xx_debugfs_exit(struct ag71xx *ag)
  13085. +{
  13086. + debugfs_remove(ag->debug.debugfs_napi_stats);
  13087. + debugfs_remove(ag->debug.debugfs_int_stats);
  13088. + debugfs_remove(ag->debug.debugfs_dir);
  13089. +}
  13090. +
  13091. +int ag71xx_debugfs_init(struct ag71xx *ag)
  13092. +{
  13093. + ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name,
  13094. + ag71xx_debugfs_root);
  13095. + if (!ag->debug.debugfs_dir)
  13096. + goto err;
  13097. +
  13098. + ag->debug.debugfs_int_stats =
  13099. + debugfs_create_file("int_stats",
  13100. + S_IRUGO,
  13101. + ag->debug.debugfs_dir,
  13102. + ag,
  13103. + &ag71xx_fops_int_stats);
  13104. + if (!ag->debug.debugfs_int_stats)
  13105. + goto err;
  13106. +
  13107. + ag->debug.debugfs_napi_stats =
  13108. + debugfs_create_file("napi_stats",
  13109. + S_IRUGO,
  13110. + ag->debug.debugfs_dir,
  13111. + ag,
  13112. + &ag71xx_fops_napi_stats);
  13113. + if (!ag->debug.debugfs_napi_stats)
  13114. + goto err;
  13115. +
  13116. + return 0;
  13117. +
  13118. + err:
  13119. + ag71xx_debugfs_exit(ag);
  13120. + return -ENOMEM;
  13121. +}
  13122. +
  13123. +int ag71xx_debugfs_root_init(void)
  13124. +{
  13125. + if (ag71xx_debugfs_root)
  13126. + return -EBUSY;
  13127. +
  13128. + ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
  13129. + if (!ag71xx_debugfs_root)
  13130. + return -ENOENT;
  13131. +
  13132. + return 0;
  13133. +}
  13134. +
  13135. +void ag71xx_debugfs_root_exit(void)
  13136. +{
  13137. + debugfs_remove(ag71xx_debugfs_root);
  13138. + ag71xx_debugfs_root = NULL;
  13139. +}
  13140. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.37/drivers/net/ag71xx/ag71xx_ethtool.c
  13141. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
  13142. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_ethtool.c 2011-01-11 20:25:48.000000000 +0100
  13143. @@ -0,0 +1,71 @@
  13144. +/*
  13145. + * Atheros AR71xx built-in ethernet mac driver
  13146. + *
  13147. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  13148. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  13149. + *
  13150. + * Based on Atheros' AG7100 driver
  13151. + *
  13152. + * This program is free software; you can redistribute it and/or modify it
  13153. + * under the terms of the GNU General Public License version 2 as published
  13154. + * by the Free Software Foundation.
  13155. + */
  13156. +
  13157. +#include "ag71xx.h"
  13158. +
  13159. +static int ag71xx_ethtool_get_settings(struct net_device *dev,
  13160. + struct ethtool_cmd *cmd)
  13161. +{
  13162. + struct ag71xx *ag = netdev_priv(dev);
  13163. + struct phy_device *phydev = ag->phy_dev;
  13164. +
  13165. + if (!phydev)
  13166. + return -ENODEV;
  13167. +
  13168. + return phy_ethtool_gset(phydev, cmd);
  13169. +}
  13170. +
  13171. +static int ag71xx_ethtool_set_settings(struct net_device *dev,
  13172. + struct ethtool_cmd *cmd)
  13173. +{
  13174. + struct ag71xx *ag = netdev_priv(dev);
  13175. + struct phy_device *phydev = ag->phy_dev;
  13176. +
  13177. + if (!phydev)
  13178. + return -ENODEV;
  13179. +
  13180. + return phy_ethtool_sset(phydev, cmd);
  13181. +}
  13182. +
  13183. +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev,
  13184. + struct ethtool_drvinfo *info)
  13185. +{
  13186. + struct ag71xx *ag = netdev_priv(dev);
  13187. +
  13188. + strcpy(info->driver, ag->pdev->dev.driver->name);
  13189. + strcpy(info->version, AG71XX_DRV_VERSION);
  13190. + strcpy(info->bus_info, dev_name(&ag->pdev->dev));
  13191. +}
  13192. +
  13193. +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev)
  13194. +{
  13195. + struct ag71xx *ag = netdev_priv(dev);
  13196. +
  13197. + return ag->msg_enable;
  13198. +}
  13199. +
  13200. +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level)
  13201. +{
  13202. + struct ag71xx *ag = netdev_priv(dev);
  13203. +
  13204. + ag->msg_enable = msg_level;
  13205. +}
  13206. +
  13207. +struct ethtool_ops ag71xx_ethtool_ops = {
  13208. + .set_settings = ag71xx_ethtool_set_settings,
  13209. + .get_settings = ag71xx_ethtool_get_settings,
  13210. + .get_drvinfo = ag71xx_ethtool_get_drvinfo,
  13211. + .get_msglevel = ag71xx_ethtool_get_msglevel,
  13212. + .set_msglevel = ag71xx_ethtool_set_msglevel,
  13213. + .get_link = ethtool_op_get_link,
  13214. +};
  13215. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.37/drivers/net/ag71xx/ag71xx_main.c
  13216. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100
  13217. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_main.c 2011-01-11 20:25:48.000000000 +0100
  13218. @@ -0,0 +1,1184 @@
  13219. +/*
  13220. + * Atheros AR71xx built-in ethernet mac driver
  13221. + *
  13222. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  13223. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  13224. + *
  13225. + * Based on Atheros' AG7100 driver
  13226. + *
  13227. + * This program is free software; you can redistribute it and/or modify it
  13228. + * under the terms of the GNU General Public License version 2 as published
  13229. + * by the Free Software Foundation.
  13230. + */
  13231. +
  13232. +#include "ag71xx.h"
  13233. +
  13234. +#define AG71XX_DEFAULT_MSG_ENABLE \
  13235. + ( NETIF_MSG_DRV \
  13236. + | NETIF_MSG_PROBE \
  13237. + | NETIF_MSG_LINK \
  13238. + | NETIF_MSG_TIMER \
  13239. + | NETIF_MSG_IFDOWN \
  13240. + | NETIF_MSG_IFUP \
  13241. + | NETIF_MSG_RX_ERR \
  13242. + | NETIF_MSG_TX_ERR )
  13243. +
  13244. +static int ag71xx_msg_level = -1;
  13245. +
  13246. +module_param_named(msg_level, ag71xx_msg_level, int, 0);
  13247. +MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
  13248. +
  13249. +static void ag71xx_dump_dma_regs(struct ag71xx *ag)
  13250. +{
  13251. + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n",
  13252. + ag->dev->name,
  13253. + ag71xx_rr(ag, AG71XX_REG_TX_CTRL),
  13254. + ag71xx_rr(ag, AG71XX_REG_TX_DESC),
  13255. + ag71xx_rr(ag, AG71XX_REG_TX_STATUS));
  13256. +
  13257. + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n",
  13258. + ag->dev->name,
  13259. + ag71xx_rr(ag, AG71XX_REG_RX_CTRL),
  13260. + ag71xx_rr(ag, AG71XX_REG_RX_DESC),
  13261. + ag71xx_rr(ag, AG71XX_REG_RX_STATUS));
  13262. +}
  13263. +
  13264. +static void ag71xx_dump_regs(struct ag71xx *ag)
  13265. +{
  13266. + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n",
  13267. + ag->dev->name,
  13268. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1),
  13269. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13270. + ag71xx_rr(ag, AG71XX_REG_MAC_IPG),
  13271. + ag71xx_rr(ag, AG71XX_REG_MAC_HDX),
  13272. + ag71xx_rr(ag, AG71XX_REG_MAC_MFL));
  13273. + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n",
  13274. + ag->dev->name,
  13275. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13276. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1),
  13277. + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2));
  13278. + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n",
  13279. + ag->dev->name,
  13280. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13281. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13282. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13283. + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n",
  13284. + ag->dev->name,
  13285. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13286. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13287. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13288. +}
  13289. +
  13290. +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
  13291. +{
  13292. + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n",
  13293. + ag->dev->name, label, intr,
  13294. + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "",
  13295. + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "",
  13296. + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "",
  13297. + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "",
  13298. + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "",
  13299. + (intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
  13300. +}
  13301. +
  13302. +static void ag71xx_ring_free(struct ag71xx_ring *ring)
  13303. +{
  13304. + kfree(ring->buf);
  13305. +
  13306. + if (ring->descs_cpu)
  13307. + dma_free_coherent(NULL, ring->size * ring->desc_size,
  13308. + ring->descs_cpu, ring->descs_dma);
  13309. +}
  13310. +
  13311. +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
  13312. +{
  13313. + int err;
  13314. + int i;
  13315. +
  13316. + ring->desc_size = sizeof(struct ag71xx_desc);
  13317. + if (ring->desc_size % cache_line_size()) {
  13318. + DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
  13319. + ring, ring->desc_size,
  13320. + roundup(ring->desc_size, cache_line_size()));
  13321. + ring->desc_size = roundup(ring->desc_size, cache_line_size());
  13322. + }
  13323. +
  13324. + ring->descs_cpu = dma_alloc_coherent(NULL, size * ring->desc_size,
  13325. + &ring->descs_dma, GFP_ATOMIC);
  13326. + if (!ring->descs_cpu) {
  13327. + err = -ENOMEM;
  13328. + goto err;
  13329. + }
  13330. +
  13331. + ring->size = size;
  13332. +
  13333. + ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL);
  13334. + if (!ring->buf) {
  13335. + err = -ENOMEM;
  13336. + goto err;
  13337. + }
  13338. +
  13339. + for (i = 0; i < size; i++) {
  13340. + ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
  13341. + DBG("ag71xx: ring %p, desc %d at %p\n",
  13342. + ring, i, ring->buf[i].desc);
  13343. + }
  13344. +
  13345. + return 0;
  13346. +
  13347. + err:
  13348. + return err;
  13349. +}
  13350. +
  13351. +static void ag71xx_ring_tx_clean(struct ag71xx *ag)
  13352. +{
  13353. + struct ag71xx_ring *ring = &ag->tx_ring;
  13354. + struct net_device *dev = ag->dev;
  13355. +
  13356. + while (ring->curr != ring->dirty) {
  13357. + u32 i = ring->dirty % AG71XX_TX_RING_SIZE;
  13358. +
  13359. + if (!ag71xx_desc_empty(ring->buf[i].desc)) {
  13360. + ring->buf[i].desc->ctrl = 0;
  13361. + dev->stats.tx_errors++;
  13362. + }
  13363. +
  13364. + if (ring->buf[i].skb)
  13365. + dev_kfree_skb_any(ring->buf[i].skb);
  13366. +
  13367. + ring->buf[i].skb = NULL;
  13368. +
  13369. + ring->dirty++;
  13370. + }
  13371. +
  13372. + /* flush descriptors */
  13373. + wmb();
  13374. +
  13375. +}
  13376. +
  13377. +static void ag71xx_ring_tx_init(struct ag71xx *ag)
  13378. +{
  13379. + struct ag71xx_ring *ring = &ag->tx_ring;
  13380. + int i;
  13381. +
  13382. + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
  13383. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13384. + ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE));
  13385. +
  13386. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13387. + ring->buf[i].skb = NULL;
  13388. + }
  13389. +
  13390. + /* flush descriptors */
  13391. + wmb();
  13392. +
  13393. + ring->curr = 0;
  13394. + ring->dirty = 0;
  13395. +}
  13396. +
  13397. +static void ag71xx_ring_rx_clean(struct ag71xx *ag)
  13398. +{
  13399. + struct ag71xx_ring *ring = &ag->rx_ring;
  13400. + int i;
  13401. +
  13402. + if (!ring->buf)
  13403. + return;
  13404. +
  13405. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++)
  13406. + if (ring->buf[i].skb) {
  13407. + dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr,
  13408. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  13409. + kfree_skb(ring->buf[i].skb);
  13410. + }
  13411. +}
  13412. +
  13413. +static int ag71xx_rx_reserve(struct ag71xx *ag)
  13414. +{
  13415. + int reserve = 0;
  13416. +
  13417. + if (ag71xx_get_pdata(ag)->is_ar724x) {
  13418. + if (!ag71xx_has_ar8216(ag))
  13419. + reserve = 2;
  13420. +
  13421. + if (ag->phy_dev)
  13422. + reserve += 4 - (ag->phy_dev->pkt_align % 4);
  13423. +
  13424. + reserve %= 4;
  13425. + }
  13426. +
  13427. + return reserve + AG71XX_RX_PKT_RESERVE;
  13428. +}
  13429. +
  13430. +
  13431. +static int ag71xx_ring_rx_init(struct ag71xx *ag)
  13432. +{
  13433. + struct ag71xx_ring *ring = &ag->rx_ring;
  13434. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13435. + unsigned int i;
  13436. + int ret;
  13437. +
  13438. + ret = 0;
  13439. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13440. + ring->buf[i].desc->next = (u32) (ring->descs_dma +
  13441. + ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE));
  13442. +
  13443. + DBG("ag71xx: RX desc at %p, next is %08x\n",
  13444. + ring->buf[i].desc,
  13445. + ring->buf[i].desc->next);
  13446. + }
  13447. +
  13448. + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
  13449. + struct sk_buff *skb;
  13450. + dma_addr_t dma_addr;
  13451. +
  13452. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13453. + if (!skb) {
  13454. + ret = -ENOMEM;
  13455. + break;
  13456. + }
  13457. +
  13458. + skb->dev = ag->dev;
  13459. + skb_reserve(skb, reserve);
  13460. +
  13461. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13462. + AG71XX_RX_PKT_SIZE,
  13463. + DMA_FROM_DEVICE);
  13464. + ring->buf[i].skb = skb;
  13465. + ring->buf[i].dma_addr = dma_addr;
  13466. + ring->buf[i].desc->data = (u32) dma_addr;
  13467. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13468. + }
  13469. +
  13470. + /* flush descriptors */
  13471. + wmb();
  13472. +
  13473. + ring->curr = 0;
  13474. + ring->dirty = 0;
  13475. +
  13476. + return ret;
  13477. +}
  13478. +
  13479. +static int ag71xx_ring_rx_refill(struct ag71xx *ag)
  13480. +{
  13481. + struct ag71xx_ring *ring = &ag->rx_ring;
  13482. + unsigned int reserve = ag71xx_rx_reserve(ag);
  13483. + unsigned int count;
  13484. +
  13485. + count = 0;
  13486. + for (; ring->curr - ring->dirty > 0; ring->dirty++) {
  13487. + unsigned int i;
  13488. +
  13489. + i = ring->dirty % AG71XX_RX_RING_SIZE;
  13490. +
  13491. + if (ring->buf[i].skb == NULL) {
  13492. + dma_addr_t dma_addr;
  13493. + struct sk_buff *skb;
  13494. +
  13495. + skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve);
  13496. + if (skb == NULL)
  13497. + break;
  13498. +
  13499. + skb_reserve(skb, reserve);
  13500. + skb->dev = ag->dev;
  13501. +
  13502. + dma_addr = dma_map_single(&ag->dev->dev, skb->data,
  13503. + AG71XX_RX_PKT_SIZE,
  13504. + DMA_FROM_DEVICE);
  13505. +
  13506. + ring->buf[i].skb = skb;
  13507. + ring->buf[i].dma_addr = dma_addr;
  13508. + ring->buf[i].desc->data = (u32) dma_addr;
  13509. + }
  13510. +
  13511. + ring->buf[i].desc->ctrl = DESC_EMPTY;
  13512. + count++;
  13513. + }
  13514. +
  13515. + /* flush descriptors */
  13516. + wmb();
  13517. +
  13518. + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count);
  13519. +
  13520. + return count;
  13521. +}
  13522. +
  13523. +static int ag71xx_rings_init(struct ag71xx *ag)
  13524. +{
  13525. + int ret;
  13526. +
  13527. + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
  13528. + if (ret)
  13529. + return ret;
  13530. +
  13531. + ag71xx_ring_tx_init(ag);
  13532. +
  13533. + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
  13534. + if (ret)
  13535. + return ret;
  13536. +
  13537. + ret = ag71xx_ring_rx_init(ag);
  13538. + return ret;
  13539. +}
  13540. +
  13541. +static void ag71xx_rings_cleanup(struct ag71xx *ag)
  13542. +{
  13543. + ag71xx_ring_rx_clean(ag);
  13544. + ag71xx_ring_free(&ag->rx_ring);
  13545. +
  13546. + ag71xx_ring_tx_clean(ag);
  13547. + ag71xx_ring_free(&ag->tx_ring);
  13548. +}
  13549. +
  13550. +static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
  13551. +{
  13552. + switch (ag->speed) {
  13553. + case SPEED_1000:
  13554. + return "1000";
  13555. + case SPEED_100:
  13556. + return "100";
  13557. + case SPEED_10:
  13558. + return "10";
  13559. + }
  13560. +
  13561. + return "?";
  13562. +}
  13563. +
  13564. +void ag71xx_link_adjust(struct ag71xx *ag)
  13565. +{
  13566. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13567. + u32 cfg2;
  13568. + u32 ifctl;
  13569. + u32 fifo5;
  13570. + u32 mii_speed;
  13571. +
  13572. + if (!ag->link) {
  13573. + netif_carrier_off(ag->dev);
  13574. + if (netif_msg_link(ag))
  13575. + printk(KERN_INFO "%s: link down\n", ag->dev->name);
  13576. + return;
  13577. + }
  13578. +
  13579. + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
  13580. + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
  13581. + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
  13582. +
  13583. + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
  13584. + ifctl &= ~(MAC_IFCTL_SPEED);
  13585. +
  13586. + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
  13587. + fifo5 &= ~FIFO_CFG5_BM;
  13588. +
  13589. + switch (ag->speed) {
  13590. + case SPEED_1000:
  13591. + mii_speed = MII_CTRL_SPEED_1000;
  13592. + cfg2 |= MAC_CFG2_IF_1000;
  13593. + fifo5 |= FIFO_CFG5_BM;
  13594. + break;
  13595. + case SPEED_100:
  13596. + mii_speed = MII_CTRL_SPEED_100;
  13597. + cfg2 |= MAC_CFG2_IF_10_100;
  13598. + ifctl |= MAC_IFCTL_SPEED;
  13599. + break;
  13600. + case SPEED_10:
  13601. + mii_speed = MII_CTRL_SPEED_10;
  13602. + cfg2 |= MAC_CFG2_IF_10_100;
  13603. + break;
  13604. + default:
  13605. + BUG();
  13606. + return;
  13607. + }
  13608. +
  13609. + if (pdata->is_ar91xx)
  13610. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
  13611. + else if (pdata->is_ar724x)
  13612. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3);
  13613. + else
  13614. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
  13615. +
  13616. + if (pdata->set_pll)
  13617. + pdata->set_pll(ag->speed);
  13618. +
  13619. + ag71xx_mii_ctrl_set_speed(ag, mii_speed);
  13620. +
  13621. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
  13622. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
  13623. + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
  13624. +
  13625. + netif_carrier_on(ag->dev);
  13626. + if (netif_msg_link(ag))
  13627. + printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n",
  13628. + ag->dev->name,
  13629. + ag71xx_speed_str(ag),
  13630. + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half");
  13631. +
  13632. + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
  13633. + ag->dev->name,
  13634. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
  13635. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
  13636. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
  13637. +
  13638. + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
  13639. + ag->dev->name,
  13640. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
  13641. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
  13642. + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
  13643. +
  13644. + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
  13645. + ag->dev->name,
  13646. + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
  13647. + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
  13648. + ag71xx_mii_ctrl_rr(ag));
  13649. +}
  13650. +
  13651. +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
  13652. +{
  13653. + u32 t;
  13654. +
  13655. + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
  13656. + | (((u32) mac[3]) << 8) | ((u32) mac[2]);
  13657. +
  13658. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
  13659. +
  13660. + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
  13661. + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
  13662. +}
  13663. +
  13664. +static void ag71xx_dma_reset(struct ag71xx *ag)
  13665. +{
  13666. + u32 val;
  13667. + int i;
  13668. +
  13669. + ag71xx_dump_dma_regs(ag);
  13670. +
  13671. + /* stop RX and TX */
  13672. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
  13673. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
  13674. +
  13675. + /* clear descriptor addresses */
  13676. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
  13677. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
  13678. +
  13679. + /* clear pending RX/TX interrupts */
  13680. + for (i = 0; i < 256; i++) {
  13681. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  13682. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13683. + }
  13684. +
  13685. + /* clear pending errors */
  13686. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
  13687. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
  13688. +
  13689. + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  13690. + if (val)
  13691. + printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n",
  13692. + ag->dev->name, val);
  13693. +
  13694. + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  13695. +
  13696. + /* mask out reserved bits */
  13697. + val &= ~0xff000000;
  13698. +
  13699. + if (val)
  13700. + printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n",
  13701. + ag->dev->name, val);
  13702. +
  13703. + ag71xx_dump_dma_regs(ag);
  13704. +}
  13705. +
  13706. +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
  13707. + MAC_CFG1_SRX | MAC_CFG1_STX)
  13708. +
  13709. +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
  13710. +
  13711. +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
  13712. + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
  13713. + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
  13714. + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
  13715. + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
  13716. + FIFO_CFG4_VT)
  13717. +
  13718. +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
  13719. + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
  13720. + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
  13721. + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
  13722. + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
  13723. + FIFO_CFG5_17 | FIFO_CFG5_SF)
  13724. +
  13725. +static void ag71xx_hw_init(struct ag71xx *ag)
  13726. +{
  13727. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  13728. +
  13729. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
  13730. + udelay(20);
  13731. +
  13732. + ar71xx_device_stop(pdata->reset_bit);
  13733. + mdelay(100);
  13734. + ar71xx_device_start(pdata->reset_bit);
  13735. + mdelay(100);
  13736. +
  13737. + /* setup MAC configuration registers */
  13738. + if (pdata->is_ar724x)
  13739. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1,
  13740. + MAC_CFG1_INIT | MAC_CFG1_TFC | MAC_CFG1_RFC);
  13741. + else
  13742. + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
  13743. +
  13744. + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
  13745. + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
  13746. +
  13747. + /* setup max frame length */
  13748. + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
  13749. +
  13750. + /* setup MII interface type */
  13751. + ag71xx_mii_ctrl_set_if(ag, pdata->mii_if);
  13752. +
  13753. + /* setup FIFO configuration registers */
  13754. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
  13755. + if (pdata->is_ar724x) {
  13756. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1);
  13757. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2);
  13758. + } else {
  13759. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
  13760. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
  13761. + }
  13762. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
  13763. + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
  13764. +
  13765. + ag71xx_dma_reset(ag);
  13766. +}
  13767. +
  13768. +static void ag71xx_hw_start(struct ag71xx *ag)
  13769. +{
  13770. + /* start RX engine */
  13771. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  13772. +
  13773. + /* enable interrupts */
  13774. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);
  13775. +}
  13776. +
  13777. +static void ag71xx_hw_stop(struct ag71xx *ag)
  13778. +{
  13779. + /* disable all interrupts */
  13780. + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);
  13781. +
  13782. + ag71xx_dma_reset(ag);
  13783. +}
  13784. +
  13785. +static int ag71xx_open(struct net_device *dev)
  13786. +{
  13787. + struct ag71xx *ag = netdev_priv(dev);
  13788. + int ret;
  13789. +
  13790. + ret = ag71xx_rings_init(ag);
  13791. + if (ret)
  13792. + goto err;
  13793. +
  13794. + napi_enable(&ag->napi);
  13795. +
  13796. + netif_carrier_off(dev);
  13797. + ag71xx_phy_start(ag);
  13798. +
  13799. + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);
  13800. + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma);
  13801. +
  13802. + ag71xx_hw_set_macaddr(ag, dev->dev_addr);
  13803. +
  13804. + ag71xx_hw_start(ag);
  13805. +
  13806. + netif_start_queue(dev);
  13807. +
  13808. + return 0;
  13809. +
  13810. + err:
  13811. + ag71xx_rings_cleanup(ag);
  13812. + return ret;
  13813. +}
  13814. +
  13815. +static int ag71xx_stop(struct net_device *dev)
  13816. +{
  13817. + struct ag71xx *ag = netdev_priv(dev);
  13818. + unsigned long flags;
  13819. +
  13820. + netif_carrier_off(dev);
  13821. + ag71xx_phy_stop(ag);
  13822. +
  13823. + spin_lock_irqsave(&ag->lock, flags);
  13824. +
  13825. + netif_stop_queue(dev);
  13826. +
  13827. + ag71xx_hw_stop(ag);
  13828. +
  13829. + napi_disable(&ag->napi);
  13830. + del_timer_sync(&ag->oom_timer);
  13831. +
  13832. + spin_unlock_irqrestore(&ag->lock, flags);
  13833. +
  13834. + ag71xx_rings_cleanup(ag);
  13835. +
  13836. + return 0;
  13837. +}
  13838. +
  13839. +static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
  13840. + struct net_device *dev)
  13841. +{
  13842. + struct ag71xx *ag = netdev_priv(dev);
  13843. + struct ag71xx_ring *ring = &ag->tx_ring;
  13844. + struct ag71xx_desc *desc;
  13845. + dma_addr_t dma_addr;
  13846. + int i;
  13847. +
  13848. + i = ring->curr % AG71XX_TX_RING_SIZE;
  13849. + desc = ring->buf[i].desc;
  13850. +
  13851. + if (!ag71xx_desc_empty(desc))
  13852. + goto err_drop;
  13853. +
  13854. + if (ag71xx_has_ar8216(ag))
  13855. + ag71xx_add_ar8216_header(ag, skb);
  13856. +
  13857. + if (skb->len <= 0) {
  13858. + DBG("%s: packet len is too small\n", ag->dev->name);
  13859. + goto err_drop;
  13860. + }
  13861. +
  13862. + dma_addr = dma_map_single(&dev->dev, skb->data, skb->len,
  13863. + DMA_TO_DEVICE);
  13864. +
  13865. + ring->buf[i].skb = skb;
  13866. +
  13867. + /* setup descriptor fields */
  13868. + desc->data = (u32) dma_addr;
  13869. + desc->ctrl = (skb->len & DESC_PKTLEN_M);
  13870. +
  13871. + /* flush descriptor */
  13872. + wmb();
  13873. +
  13874. + ring->curr++;
  13875. + if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) {
  13876. + DBG("%s: tx queue full\n", ag->dev->name);
  13877. + netif_stop_queue(dev);
  13878. + }
  13879. +
  13880. + DBG("%s: packet injected into TX queue\n", ag->dev->name);
  13881. +
  13882. + /* enable TX engine */
  13883. + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
  13884. +
  13885. + return NETDEV_TX_OK;
  13886. +
  13887. + err_drop:
  13888. + dev->stats.tx_dropped++;
  13889. +
  13890. + dev_kfree_skb(skb);
  13891. + return NETDEV_TX_OK;
  13892. +}
  13893. +
  13894. +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  13895. +{
  13896. + struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;
  13897. + struct ag71xx *ag = netdev_priv(dev);
  13898. + int ret;
  13899. +
  13900. + switch (cmd) {
  13901. + case SIOCETHTOOL:
  13902. + if (ag->phy_dev == NULL)
  13903. + break;
  13904. +
  13905. + spin_lock_irq(&ag->lock);
  13906. + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data);
  13907. + spin_unlock_irq(&ag->lock);
  13908. + return ret;
  13909. +
  13910. + case SIOCSIFHWADDR:
  13911. + if (copy_from_user
  13912. + (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
  13913. + return -EFAULT;
  13914. + return 0;
  13915. +
  13916. + case SIOCGIFHWADDR:
  13917. + if (copy_to_user
  13918. + (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
  13919. + return -EFAULT;
  13920. + return 0;
  13921. +
  13922. + case SIOCGMIIPHY:
  13923. + case SIOCGMIIREG:
  13924. + case SIOCSMIIREG:
  13925. + if (ag->phy_dev == NULL)
  13926. + break;
  13927. +
  13928. + return phy_mii_ioctl(ag->phy_dev, data, cmd);
  13929. +
  13930. + default:
  13931. + break;
  13932. + }
  13933. +
  13934. + return -EOPNOTSUPP;
  13935. +}
  13936. +
  13937. +static void ag71xx_oom_timer_handler(unsigned long data)
  13938. +{
  13939. + struct net_device *dev = (struct net_device *) data;
  13940. + struct ag71xx *ag = netdev_priv(dev);
  13941. +
  13942. + napi_schedule(&ag->napi);
  13943. +}
  13944. +
  13945. +static void ag71xx_tx_timeout(struct net_device *dev)
  13946. +{
  13947. + struct ag71xx *ag = netdev_priv(dev);
  13948. +
  13949. + if (netif_msg_tx_err(ag))
  13950. + printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
  13951. +
  13952. + schedule_work(&ag->restart_work);
  13953. +}
  13954. +
  13955. +static void ag71xx_restart_work_func(struct work_struct *work)
  13956. +{
  13957. + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
  13958. +
  13959. + ag71xx_stop(ag->dev);
  13960. + ag71xx_open(ag->dev);
  13961. +}
  13962. +
  13963. +static int ag71xx_tx_packets(struct ag71xx *ag)
  13964. +{
  13965. + struct ag71xx_ring *ring = &ag->tx_ring;
  13966. + int sent;
  13967. +
  13968. + DBG("%s: processing TX ring\n", ag->dev->name);
  13969. +
  13970. + sent = 0;
  13971. + while (ring->dirty != ring->curr) {
  13972. + unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE;
  13973. + struct ag71xx_desc *desc = ring->buf[i].desc;
  13974. + struct sk_buff *skb = ring->buf[i].skb;
  13975. +
  13976. + if (!ag71xx_desc_empty(desc))
  13977. + break;
  13978. +
  13979. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
  13980. +
  13981. + ag->dev->stats.tx_bytes += skb->len;
  13982. + ag->dev->stats.tx_packets++;
  13983. +
  13984. + dev_kfree_skb_any(skb);
  13985. + ring->buf[i].skb = NULL;
  13986. +
  13987. + ring->dirty++;
  13988. + sent++;
  13989. + }
  13990. +
  13991. + DBG("%s: %d packets sent out\n", ag->dev->name, sent);
  13992. +
  13993. + if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP)
  13994. + netif_wake_queue(ag->dev);
  13995. +
  13996. + return sent;
  13997. +}
  13998. +
  13999. +static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
  14000. +{
  14001. + struct net_device *dev = ag->dev;
  14002. + struct ag71xx_ring *ring = &ag->rx_ring;
  14003. + int done = 0;
  14004. +
  14005. + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n",
  14006. + dev->name, limit, ring->curr, ring->dirty);
  14007. +
  14008. + while (done < limit) {
  14009. + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
  14010. + struct ag71xx_desc *desc = ring->buf[i].desc;
  14011. + struct sk_buff *skb;
  14012. + int pktlen;
  14013. + int err = 0;
  14014. +
  14015. + if (ag71xx_desc_empty(desc))
  14016. + break;
  14017. +
  14018. + if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) {
  14019. + ag71xx_assert(0);
  14020. + break;
  14021. + }
  14022. +
  14023. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
  14024. +
  14025. + skb = ring->buf[i].skb;
  14026. + pktlen = ag71xx_desc_pktlen(desc);
  14027. + pktlen -= ETH_FCS_LEN;
  14028. +
  14029. + dma_unmap_single(&dev->dev, ring->buf[i].dma_addr,
  14030. + AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE);
  14031. +
  14032. + dev->last_rx = jiffies;
  14033. + dev->stats.rx_packets++;
  14034. + dev->stats.rx_bytes += pktlen;
  14035. +
  14036. + skb_put(skb, pktlen);
  14037. + if (ag71xx_has_ar8216(ag))
  14038. + err = ag71xx_remove_ar8216_header(ag, skb, pktlen);
  14039. +
  14040. + if (err) {
  14041. + dev->stats.rx_dropped++;
  14042. + kfree_skb(skb);
  14043. + } else {
  14044. + skb->dev = dev;
  14045. + skb->ip_summed = CHECKSUM_NONE;
  14046. + if (ag->phy_dev) {
  14047. + ag->phy_dev->netif_receive_skb(skb);
  14048. + } else {
  14049. + skb->protocol = eth_type_trans(skb, dev);
  14050. + netif_receive_skb(skb);
  14051. + }
  14052. + }
  14053. +
  14054. + ring->buf[i].skb = NULL;
  14055. + done++;
  14056. +
  14057. + ring->curr++;
  14058. + }
  14059. +
  14060. + ag71xx_ring_rx_refill(ag);
  14061. +
  14062. + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n",
  14063. + dev->name, ring->curr, ring->dirty, done);
  14064. +
  14065. + return done;
  14066. +}
  14067. +
  14068. +static int ag71xx_poll(struct napi_struct *napi, int limit)
  14069. +{
  14070. + struct ag71xx *ag = container_of(napi, struct ag71xx, napi);
  14071. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14072. + struct net_device *dev = ag->dev;
  14073. + struct ag71xx_ring *rx_ring;
  14074. + unsigned long flags;
  14075. + u32 status;
  14076. + int tx_done;
  14077. + int rx_done;
  14078. +
  14079. + pdata->ddr_flush();
  14080. + tx_done = ag71xx_tx_packets(ag);
  14081. +
  14082. + DBG("%s: processing RX ring\n", dev->name);
  14083. + rx_done = ag71xx_rx_packets(ag, limit);
  14084. +
  14085. + ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done);
  14086. +
  14087. + rx_ring = &ag->rx_ring;
  14088. + if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL)
  14089. + goto oom;
  14090. +
  14091. + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
  14092. + if (unlikely(status & RX_STATUS_OF)) {
  14093. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF);
  14094. + dev->stats.rx_fifo_errors++;
  14095. +
  14096. + /* restart RX */
  14097. + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
  14098. + }
  14099. +
  14100. + if (rx_done < limit) {
  14101. + if (status & RX_STATUS_PR)
  14102. + goto more;
  14103. +
  14104. + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
  14105. + if (status & TX_STATUS_PS)
  14106. + goto more;
  14107. +
  14108. + DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n",
  14109. + dev->name, rx_done, tx_done, limit);
  14110. +
  14111. + napi_complete(napi);
  14112. +
  14113. + /* enable interrupts */
  14114. + spin_lock_irqsave(&ag->lock, flags);
  14115. + ag71xx_int_enable(ag, AG71XX_INT_POLL);
  14116. + spin_unlock_irqrestore(&ag->lock, flags);
  14117. + return rx_done;
  14118. + }
  14119. +
  14120. + more:
  14121. + DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n",
  14122. + dev->name, rx_done, tx_done, limit);
  14123. + return rx_done;
  14124. +
  14125. + oom:
  14126. + if (netif_msg_rx_err(ag))
  14127. + printk(KERN_DEBUG "%s: out of memory\n", dev->name);
  14128. +
  14129. + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
  14130. + napi_complete(napi);
  14131. + return 0;
  14132. +}
  14133. +
  14134. +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id)
  14135. +{
  14136. + struct net_device *dev = dev_id;
  14137. + struct ag71xx *ag = netdev_priv(dev);
  14138. + u32 status;
  14139. +
  14140. + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS);
  14141. + ag71xx_dump_intr(ag, "raw", status);
  14142. +
  14143. + if (unlikely(!status))
  14144. + return IRQ_NONE;
  14145. +
  14146. + if (unlikely(status & AG71XX_INT_ERR)) {
  14147. + if (status & AG71XX_INT_TX_BE) {
  14148. + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE);
  14149. + dev_err(&dev->dev, "TX BUS error\n");
  14150. + }
  14151. + if (status & AG71XX_INT_RX_BE) {
  14152. + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE);
  14153. + dev_err(&dev->dev, "RX BUS error\n");
  14154. + }
  14155. + }
  14156. +
  14157. + if (likely(status & AG71XX_INT_POLL)) {
  14158. + ag71xx_int_disable(ag, AG71XX_INT_POLL);
  14159. + DBG("%s: enable polling mode\n", dev->name);
  14160. + napi_schedule(&ag->napi);
  14161. + }
  14162. +
  14163. + ag71xx_debugfs_update_int_stats(ag, status);
  14164. +
  14165. + return IRQ_HANDLED;
  14166. +}
  14167. +
  14168. +static void ag71xx_set_multicast_list(struct net_device *dev)
  14169. +{
  14170. + /* TODO */
  14171. +}
  14172. +
  14173. +#ifdef CONFIG_NET_POLL_CONTROLLER
  14174. +/*
  14175. + * Polling 'interrupt' - used by things like netconsole to send skbs
  14176. + * without having to re-enable interrupts. It's not called while
  14177. + * the interrupt routine is executing.
  14178. + */
  14179. +static void ag71xx_netpoll(struct net_device *dev)
  14180. +{
  14181. + disable_irq(dev->irq);
  14182. + ag71xx_interrupt(dev->irq, dev);
  14183. + enable_irq(dev->irq);
  14184. +}
  14185. +#endif
  14186. +
  14187. +static const struct net_device_ops ag71xx_netdev_ops = {
  14188. + .ndo_open = ag71xx_open,
  14189. + .ndo_stop = ag71xx_stop,
  14190. + .ndo_start_xmit = ag71xx_hard_start_xmit,
  14191. + .ndo_set_multicast_list = ag71xx_set_multicast_list,
  14192. + .ndo_do_ioctl = ag71xx_do_ioctl,
  14193. + .ndo_tx_timeout = ag71xx_tx_timeout,
  14194. + .ndo_change_mtu = eth_change_mtu,
  14195. + .ndo_set_mac_address = eth_mac_addr,
  14196. + .ndo_validate_addr = eth_validate_addr,
  14197. +#ifdef CONFIG_NET_POLL_CONTROLLER
  14198. + .ndo_poll_controller = ag71xx_netpoll,
  14199. +#endif
  14200. +};
  14201. +
  14202. +static int __init ag71xx_probe(struct platform_device *pdev)
  14203. +{
  14204. + struct net_device *dev;
  14205. + struct resource *res;
  14206. + struct ag71xx *ag;
  14207. + struct ag71xx_platform_data *pdata;
  14208. + int err;
  14209. +
  14210. + pdata = pdev->dev.platform_data;
  14211. + if (!pdata) {
  14212. + dev_err(&pdev->dev, "no platform data specified\n");
  14213. + err = -ENXIO;
  14214. + goto err_out;
  14215. + }
  14216. +
  14217. + if (pdata->mii_bus_dev == NULL) {
  14218. + dev_err(&pdev->dev, "no MII bus device specified\n");
  14219. + err = -EINVAL;
  14220. + goto err_out;
  14221. + }
  14222. +
  14223. + dev = alloc_etherdev(sizeof(*ag));
  14224. + if (!dev) {
  14225. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  14226. + err = -ENOMEM;
  14227. + goto err_out;
  14228. + }
  14229. +
  14230. + SET_NETDEV_DEV(dev, &pdev->dev);
  14231. +
  14232. + ag = netdev_priv(dev);
  14233. + ag->pdev = pdev;
  14234. + ag->dev = dev;
  14235. + ag->msg_enable = netif_msg_init(ag71xx_msg_level,
  14236. + AG71XX_DEFAULT_MSG_ENABLE);
  14237. + spin_lock_init(&ag->lock);
  14238. +
  14239. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base");
  14240. + if (!res) {
  14241. + dev_err(&pdev->dev, "no mac_base resource found\n");
  14242. + err = -ENXIO;
  14243. + goto err_out;
  14244. + }
  14245. +
  14246. + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14247. + if (!ag->mac_base) {
  14248. + dev_err(&pdev->dev, "unable to ioremap mac_base\n");
  14249. + err = -ENOMEM;
  14250. + goto err_free_dev;
  14251. + }
  14252. +
  14253. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl");
  14254. + if (!res) {
  14255. + dev_err(&pdev->dev, "no mii_ctrl resource found\n");
  14256. + err = -ENXIO;
  14257. + goto err_unmap_base;
  14258. + }
  14259. +
  14260. + ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1);
  14261. + if (!ag->mii_ctrl) {
  14262. + dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n");
  14263. + err = -ENOMEM;
  14264. + goto err_unmap_base;
  14265. + }
  14266. +
  14267. + dev->irq = platform_get_irq(pdev, 0);
  14268. + err = request_irq(dev->irq, ag71xx_interrupt,
  14269. + IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
  14270. + dev->name, dev);
  14271. + if (err) {
  14272. + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
  14273. + goto err_unmap_mii_ctrl;
  14274. + }
  14275. +
  14276. + dev->base_addr = (unsigned long)ag->mac_base;
  14277. + dev->netdev_ops = &ag71xx_netdev_ops;
  14278. + dev->ethtool_ops = &ag71xx_ethtool_ops;
  14279. +
  14280. + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
  14281. +
  14282. + init_timer(&ag->oom_timer);
  14283. + ag->oom_timer.data = (unsigned long) dev;
  14284. + ag->oom_timer.function = ag71xx_oom_timer_handler;
  14285. +
  14286. + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
  14287. +
  14288. + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
  14289. +
  14290. + err = register_netdev(dev);
  14291. + if (err) {
  14292. + dev_err(&pdev->dev, "unable to register net device\n");
  14293. + goto err_free_irq;
  14294. + }
  14295. +
  14296. + printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n",
  14297. + dev->name, dev->base_addr, dev->irq);
  14298. +
  14299. + ag71xx_dump_regs(ag);
  14300. +
  14301. + ag71xx_hw_init(ag);
  14302. +
  14303. + ag71xx_dump_regs(ag);
  14304. +
  14305. + err = ag71xx_phy_connect(ag);
  14306. + if (err)
  14307. + goto err_unregister_netdev;
  14308. +
  14309. + err = ag71xx_debugfs_init(ag);
  14310. + if (err)
  14311. + goto err_phy_disconnect;
  14312. +
  14313. + platform_set_drvdata(pdev, dev);
  14314. +
  14315. + return 0;
  14316. +
  14317. + err_phy_disconnect:
  14318. + ag71xx_phy_disconnect(ag);
  14319. + err_unregister_netdev:
  14320. + unregister_netdev(dev);
  14321. + err_free_irq:
  14322. + free_irq(dev->irq, dev);
  14323. + err_unmap_mii_ctrl:
  14324. + iounmap(ag->mii_ctrl);
  14325. + err_unmap_base:
  14326. + iounmap(ag->mac_base);
  14327. + err_free_dev:
  14328. + kfree(dev);
  14329. + err_out:
  14330. + platform_set_drvdata(pdev, NULL);
  14331. + return err;
  14332. +}
  14333. +
  14334. +static int __exit ag71xx_remove(struct platform_device *pdev)
  14335. +{
  14336. + struct net_device *dev = platform_get_drvdata(pdev);
  14337. +
  14338. + if (dev) {
  14339. + struct ag71xx *ag = netdev_priv(dev);
  14340. +
  14341. + ag71xx_debugfs_exit(ag);
  14342. + ag71xx_phy_disconnect(ag);
  14343. + unregister_netdev(dev);
  14344. + free_irq(dev->irq, dev);
  14345. + iounmap(ag->mii_ctrl);
  14346. + iounmap(ag->mac_base);
  14347. + kfree(dev);
  14348. + platform_set_drvdata(pdev, NULL);
  14349. + }
  14350. +
  14351. + return 0;
  14352. +}
  14353. +
  14354. +static struct platform_driver ag71xx_driver = {
  14355. + .probe = ag71xx_probe,
  14356. + .remove = __exit_p(ag71xx_remove),
  14357. + .driver = {
  14358. + .name = AG71XX_DRV_NAME,
  14359. + }
  14360. +};
  14361. +
  14362. +static int __init ag71xx_module_init(void)
  14363. +{
  14364. + int ret;
  14365. +
  14366. + ret = ag71xx_debugfs_root_init();
  14367. + if (ret)
  14368. + goto err_out;
  14369. +
  14370. + ret = ag71xx_mdio_driver_init();
  14371. + if (ret)
  14372. + goto err_debugfs_exit;
  14373. +
  14374. + ret = platform_driver_register(&ag71xx_driver);
  14375. + if (ret)
  14376. + goto err_mdio_exit;
  14377. +
  14378. + return 0;
  14379. +
  14380. + err_mdio_exit:
  14381. + ag71xx_mdio_driver_exit();
  14382. + err_debugfs_exit:
  14383. + ag71xx_debugfs_root_exit();
  14384. + err_out:
  14385. + return ret;
  14386. +}
  14387. +
  14388. +static void __exit ag71xx_module_exit(void)
  14389. +{
  14390. + platform_driver_unregister(&ag71xx_driver);
  14391. + ag71xx_mdio_driver_exit();
  14392. + ag71xx_debugfs_root_exit();
  14393. +}
  14394. +
  14395. +module_init(ag71xx_module_init);
  14396. +module_exit(ag71xx_module_exit);
  14397. +
  14398. +MODULE_VERSION(AG71XX_DRV_VERSION);
  14399. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  14400. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  14401. +MODULE_LICENSE("GPL v2");
  14402. +MODULE_ALIAS("platform:" AG71XX_DRV_NAME);
  14403. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.37/drivers/net/ag71xx/ag71xx_mdio.c
  14404. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100
  14405. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_mdio.c 2011-01-11 20:25:48.000000000 +0100
  14406. @@ -0,0 +1,243 @@
  14407. +/*
  14408. + * Atheros AR71xx built-in ethernet mac driver
  14409. + *
  14410. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14411. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14412. + *
  14413. + * Based on Atheros' AG7100 driver
  14414. + *
  14415. + * This program is free software; you can redistribute it and/or modify it
  14416. + * under the terms of the GNU General Public License version 2 as published
  14417. + * by the Free Software Foundation.
  14418. + */
  14419. +
  14420. +#include "ag71xx.h"
  14421. +
  14422. +#define AG71XX_MDIO_RETRY 1000
  14423. +#define AG71XX_MDIO_DELAY 5
  14424. +
  14425. +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg,
  14426. + u32 value)
  14427. +{
  14428. + void __iomem *r;
  14429. +
  14430. + r = am->mdio_base + reg;
  14431. + __raw_writel(value, r);
  14432. +
  14433. + /* flush write */
  14434. + (void) __raw_readl(r);
  14435. +}
  14436. +
  14437. +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg)
  14438. +{
  14439. + return __raw_readl(am->mdio_base + reg);
  14440. +}
  14441. +
  14442. +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
  14443. +{
  14444. + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n",
  14445. + am->mii_bus->name,
  14446. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG),
  14447. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD),
  14448. + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR));
  14449. + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n",
  14450. + am->mii_bus->name,
  14451. + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL),
  14452. + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS),
  14453. + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
  14454. +}
  14455. +
  14456. +static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
  14457. +{
  14458. + int ret;
  14459. + int i;
  14460. +
  14461. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14462. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14463. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14464. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ);
  14465. +
  14466. + i = AG71XX_MDIO_RETRY;
  14467. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14468. + if (i-- == 0) {
  14469. + printk(KERN_ERR "%s: mii_read timed out\n",
  14470. + am->mii_bus->name);
  14471. + ret = 0xffff;
  14472. + goto out;
  14473. + }
  14474. + udelay(AG71XX_MDIO_DELAY);
  14475. + }
  14476. +
  14477. + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff;
  14478. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
  14479. +
  14480. + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
  14481. +
  14482. + out:
  14483. + return ret;
  14484. +}
  14485. +
  14486. +static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am,
  14487. + int addr, int reg, u16 val)
  14488. +{
  14489. + int i;
  14490. +
  14491. + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
  14492. +
  14493. + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR,
  14494. + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
  14495. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val);
  14496. +
  14497. + i = AG71XX_MDIO_RETRY;
  14498. + while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
  14499. + if (i-- == 0) {
  14500. + printk(KERN_ERR "%s: mii_write timed out\n",
  14501. + am->mii_bus->name);
  14502. + break;
  14503. + }
  14504. + udelay(AG71XX_MDIO_DELAY);
  14505. + }
  14506. +}
  14507. +
  14508. +static int ag71xx_mdio_reset(struct mii_bus *bus)
  14509. +{
  14510. + struct ag71xx_mdio *am = bus->priv;
  14511. + u32 t;
  14512. +
  14513. + if (am->pdata->is_ar7240)
  14514. + t = MII_CFG_CLK_DIV_6;
  14515. + else
  14516. + t = MII_CFG_CLK_DIV_28;
  14517. +
  14518. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);
  14519. + udelay(100);
  14520. +
  14521. + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t);
  14522. + udelay(100);
  14523. +
  14524. + return 0;
  14525. +}
  14526. +
  14527. +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
  14528. +{
  14529. + struct ag71xx_mdio *am = bus->priv;
  14530. +
  14531. + return ag71xx_mdio_mii_read(am, addr, reg);
  14532. +}
  14533. +
  14534. +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
  14535. +{
  14536. + struct ag71xx_mdio *am = bus->priv;
  14537. +
  14538. + ag71xx_mdio_mii_write(am, addr, reg, val);
  14539. + return 0;
  14540. +}
  14541. +
  14542. +static int __init ag71xx_mdio_probe(struct platform_device *pdev)
  14543. +{
  14544. + struct ag71xx_mdio_platform_data *pdata;
  14545. + struct ag71xx_mdio *am;
  14546. + struct resource *res;
  14547. + int i;
  14548. + int err;
  14549. +
  14550. + pdata = pdev->dev.platform_data;
  14551. + if (!pdata) {
  14552. + dev_err(&pdev->dev, "no platform data specified\n");
  14553. + return -EINVAL;
  14554. + }
  14555. +
  14556. + am = kzalloc(sizeof(*am), GFP_KERNEL);
  14557. + if (!am) {
  14558. + err = -ENOMEM;
  14559. + goto err_out;
  14560. + }
  14561. +
  14562. + am->pdata = pdata;
  14563. +
  14564. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  14565. + if (!res) {
  14566. + dev_err(&pdev->dev, "no iomem resource found\n");
  14567. + err = -ENXIO;
  14568. + goto err_out;
  14569. + }
  14570. +
  14571. + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);
  14572. + if (!am->mdio_base) {
  14573. + dev_err(&pdev->dev, "unable to ioremap registers\n");
  14574. + err = -ENOMEM;
  14575. + goto err_free_mdio;
  14576. + }
  14577. +
  14578. + am->mii_bus = mdiobus_alloc();
  14579. + if (am->mii_bus == NULL) {
  14580. + err = -ENOMEM;
  14581. + goto err_iounmap;
  14582. + }
  14583. +
  14584. + am->mii_bus->name = "ag71xx_mdio";
  14585. + am->mii_bus->read = ag71xx_mdio_read;
  14586. + am->mii_bus->write = ag71xx_mdio_write;
  14587. + am->mii_bus->reset = ag71xx_mdio_reset;
  14588. + am->mii_bus->irq = am->mii_irq;
  14589. + am->mii_bus->priv = am;
  14590. + am->mii_bus->parent = &pdev->dev;
  14591. + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
  14592. + am->mii_bus->phy_mask = pdata->phy_mask;
  14593. +
  14594. + for (i = 0; i < PHY_MAX_ADDR; i++)
  14595. + am->mii_irq[i] = PHY_POLL;
  14596. +
  14597. + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0);
  14598. +
  14599. + err = mdiobus_register(am->mii_bus);
  14600. + if (err)
  14601. + goto err_free_bus;
  14602. +
  14603. + ag71xx_mdio_dump_regs(am);
  14604. +
  14605. + platform_set_drvdata(pdev, am);
  14606. + return 0;
  14607. +
  14608. + err_free_bus:
  14609. + mdiobus_free(am->mii_bus);
  14610. + err_iounmap:
  14611. + iounmap(am->mdio_base);
  14612. + err_free_mdio:
  14613. + kfree(am);
  14614. + err_out:
  14615. + return err;
  14616. +}
  14617. +
  14618. +static int __exit ag71xx_mdio_remove(struct platform_device *pdev)
  14619. +{
  14620. + struct ag71xx_mdio *am = platform_get_drvdata(pdev);
  14621. +
  14622. + if (am) {
  14623. + mdiobus_unregister(am->mii_bus);
  14624. + mdiobus_free(am->mii_bus);
  14625. + iounmap(am->mdio_base);
  14626. + kfree(am);
  14627. + platform_set_drvdata(pdev, NULL);
  14628. + }
  14629. +
  14630. + return 0;
  14631. +}
  14632. +
  14633. +static struct platform_driver ag71xx_mdio_driver = {
  14634. + .probe = ag71xx_mdio_probe,
  14635. + .remove = __exit_p(ag71xx_mdio_remove),
  14636. + .driver = {
  14637. + .name = "ag71xx-mdio",
  14638. + }
  14639. +};
  14640. +
  14641. +int ag71xx_mdio_driver_init(void)
  14642. +{
  14643. + return platform_driver_register(&ag71xx_mdio_driver);
  14644. +}
  14645. +
  14646. +void ag71xx_mdio_driver_exit(void)
  14647. +{
  14648. + platform_driver_unregister(&ag71xx_mdio_driver);
  14649. +}
  14650. diff -Nur linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.37/drivers/net/ag71xx/ag71xx_phy.c
  14651. --- linux-2.6.37.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100
  14652. +++ linux-2.6.37/drivers/net/ag71xx/ag71xx_phy.c 2011-01-11 20:25:48.000000000 +0100
  14653. @@ -0,0 +1,213 @@
  14654. +/*
  14655. + * Atheros AR71xx built-in ethernet mac driver
  14656. + *
  14657. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  14658. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  14659. + *
  14660. + * Based on Atheros' AG7100 driver
  14661. + *
  14662. + * This program is free software; you can redistribute it and/or modify it
  14663. + * under the terms of the GNU General Public License version 2 as published
  14664. + * by the Free Software Foundation.
  14665. + */
  14666. +
  14667. +#include "ag71xx.h"
  14668. +
  14669. +static void ag71xx_phy_link_adjust(struct net_device *dev)
  14670. +{
  14671. + struct ag71xx *ag = netdev_priv(dev);
  14672. + struct phy_device *phydev = ag->phy_dev;
  14673. + unsigned long flags;
  14674. + int status_change = 0;
  14675. +
  14676. + spin_lock_irqsave(&ag->lock, flags);
  14677. +
  14678. + if (phydev->link) {
  14679. + if (ag->duplex != phydev->duplex
  14680. + || ag->speed != phydev->speed) {
  14681. + status_change = 1;
  14682. + }
  14683. + }
  14684. +
  14685. + if (phydev->link != ag->link)
  14686. + status_change = 1;
  14687. +
  14688. + ag->link = phydev->link;
  14689. + ag->duplex = phydev->duplex;
  14690. + ag->speed = phydev->speed;
  14691. +
  14692. + if (status_change)
  14693. + ag71xx_link_adjust(ag);
  14694. +
  14695. + spin_unlock_irqrestore(&ag->lock, flags);
  14696. +}
  14697. +
  14698. +void ag71xx_phy_start(struct ag71xx *ag)
  14699. +{
  14700. + if (ag->phy_dev) {
  14701. + phy_start(ag->phy_dev);
  14702. + } else {
  14703. + ag->link = 1;
  14704. + ag71xx_link_adjust(ag);
  14705. + }
  14706. +}
  14707. +
  14708. +void ag71xx_phy_stop(struct ag71xx *ag)
  14709. +{
  14710. + if (ag->phy_dev) {
  14711. + phy_stop(ag->phy_dev);
  14712. + } else {
  14713. + ag->link = 0;
  14714. + ag71xx_link_adjust(ag);
  14715. + }
  14716. +}
  14717. +
  14718. +static int ag71xx_phy_connect_fixed(struct ag71xx *ag)
  14719. +{
  14720. + struct net_device *dev = ag->dev;
  14721. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14722. + int ret = 0;
  14723. +
  14724. + /* use fixed settings */
  14725. + switch (pdata->speed) {
  14726. + case SPEED_10:
  14727. + case SPEED_100:
  14728. + case SPEED_1000:
  14729. + break;
  14730. + default:
  14731. + printk(KERN_ERR "%s: invalid speed specified\n", dev->name);
  14732. + ret = -EINVAL;
  14733. + break;
  14734. + }
  14735. +
  14736. + printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name);
  14737. +
  14738. + ag->duplex = pdata->duplex;
  14739. + ag->speed = pdata->speed;
  14740. +
  14741. + return ret;
  14742. +}
  14743. +
  14744. +static int ag71xx_phy_connect_multi(struct ag71xx *ag)
  14745. +{
  14746. + struct net_device *dev = ag->dev;
  14747. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14748. + struct phy_device *phydev = NULL;
  14749. + int phy_addr;
  14750. + int ret = 0;
  14751. +
  14752. + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
  14753. + if (!(pdata->phy_mask & (1 << phy_addr)))
  14754. + continue;
  14755. +
  14756. + if (ag->mii_bus->phy_map[phy_addr] == NULL)
  14757. + continue;
  14758. +
  14759. + DBG("%s: PHY found at %s, uid=%08x\n",
  14760. + dev->name,
  14761. + dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),
  14762. + ag->mii_bus->phy_map[phy_addr]->phy_id);
  14763. +
  14764. + if (phydev == NULL)
  14765. + phydev = ag->mii_bus->phy_map[phy_addr];
  14766. + }
  14767. +
  14768. + if (!phydev) {
  14769. + printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",
  14770. + dev->name, pdata->phy_mask);
  14771. + return -ENODEV;
  14772. + }
  14773. +
  14774. + ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev),
  14775. + &ag71xx_phy_link_adjust, 0,
  14776. + pdata->phy_if_mode);
  14777. +
  14778. + if (IS_ERR(ag->phy_dev)) {
  14779. + printk(KERN_ERR "%s: could not connect to PHY at %s\n",
  14780. + dev->name, dev_name(&phydev->dev));
  14781. + return PTR_ERR(ag->phy_dev);
  14782. + }
  14783. +
  14784. + /* mask with MAC supported features */
  14785. + if (pdata->has_gbit)
  14786. + phydev->supported &= PHY_GBIT_FEATURES;
  14787. + else
  14788. + phydev->supported &= PHY_BASIC_FEATURES;
  14789. +
  14790. + phydev->advertising = phydev->supported;
  14791. +
  14792. + printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
  14793. + dev->name, dev_name(&phydev->dev),
  14794. + phydev->phy_id, phydev->drv->name);
  14795. +
  14796. + ag->link = 0;
  14797. + ag->speed = 0;
  14798. + ag->duplex = -1;
  14799. +
  14800. + return ret;
  14801. +}
  14802. +
  14803. +static int dev_is_class(struct device *dev, void *class)
  14804. +{
  14805. + if (dev->class != NULL && !strcmp(dev->class->name, class))
  14806. + return 1;
  14807. +
  14808. + return 0;
  14809. +}
  14810. +
  14811. +static struct device *dev_find_class(struct device *parent, char *class)
  14812. +{
  14813. + if (dev_is_class(parent, class)) {
  14814. + get_device(parent);
  14815. + return parent;
  14816. + }
  14817. +
  14818. + return device_find_child(parent, class, dev_is_class);
  14819. +}
  14820. +
  14821. +static struct mii_bus *dev_to_mii_bus(struct device *dev)
  14822. +{
  14823. + struct device *d;
  14824. +
  14825. + d = dev_find_class(dev, "mdio_bus");
  14826. + if (d != NULL) {
  14827. + struct mii_bus *bus;
  14828. +
  14829. + bus = to_mii_bus(d);
  14830. + put_device(d);
  14831. +
  14832. + return bus;
  14833. + }
  14834. +
  14835. + return NULL;
  14836. +}
  14837. +
  14838. +int ag71xx_phy_connect(struct ag71xx *ag)
  14839. +{
  14840. + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
  14841. +
  14842. + ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev);
  14843. + if (ag->mii_bus == NULL) {
  14844. + printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n",
  14845. + ag->dev->name, dev_name(pdata->mii_bus_dev));
  14846. + return -ENODEV;
  14847. + }
  14848. +
  14849. + /* Reset the mdio bus explicitly */
  14850. + if (ag->mii_bus->reset) {
  14851. + mutex_lock(&ag->mii_bus->mdio_lock);
  14852. + ag->mii_bus->reset(ag->mii_bus);
  14853. + mutex_unlock(&ag->mii_bus->mdio_lock);
  14854. + }
  14855. +
  14856. + if (pdata->phy_mask)
  14857. + return ag71xx_phy_connect_multi(ag);
  14858. +
  14859. + return ag71xx_phy_connect_fixed(ag);
  14860. +}
  14861. +
  14862. +void ag71xx_phy_disconnect(struct ag71xx *ag)
  14863. +{
  14864. + if (ag->phy_dev)
  14865. + phy_disconnect(ag->phy_dev);
  14866. +}
  14867. diff -Nur linux-2.6.37.orig/drivers/net/phy/Kconfig linux-2.6.37/drivers/net/phy/Kconfig
  14868. --- linux-2.6.37.orig/drivers/net/phy/Kconfig 2011-01-05 01:50:19.000000000 +0100
  14869. +++ linux-2.6.37/drivers/net/phy/Kconfig 2011-01-11 20:25:48.000000000 +0100
  14870. @@ -92,6 +92,10 @@
  14871. ---help---
  14872. Supports the KSZ9021, VSC8201, KS8001 PHYs.
  14873. +config IP175C_PHY
  14874. + tristate "Driver for IC+ IP175C/IP178C switches"
  14875. + select SWCONFIG
  14876. +
  14877. config FIXED_PHY
  14878. bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
  14879. depends on PHYLIB=y
  14880. diff -Nur linux-2.6.37.orig/drivers/net/phy/phy.c linux-2.6.37/drivers/net/phy/phy.c
  14881. --- linux-2.6.37.orig/drivers/net/phy/phy.c 2011-01-05 01:50:19.000000000 +0100
  14882. +++ linux-2.6.37/drivers/net/phy/phy.c 2011-01-11 20:25:48.000000000 +0100
  14883. @@ -297,6 +297,50 @@
  14884. }
  14885. EXPORT_SYMBOL(phy_ethtool_gset);
  14886. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  14887. +{
  14888. + u32 cmd;
  14889. + int tmp;
  14890. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  14891. + struct ethtool_value edata = { ETHTOOL_GLINK };
  14892. +
  14893. + if (get_user(cmd, (u32 *) useraddr))
  14894. + return -EFAULT;
  14895. +
  14896. + switch (cmd) {
  14897. + case ETHTOOL_GSET:
  14898. + phy_ethtool_gset(phydev, &ecmd);
  14899. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  14900. + return -EFAULT;
  14901. + return 0;
  14902. +
  14903. + case ETHTOOL_SSET:
  14904. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  14905. + return -EFAULT;
  14906. + return phy_ethtool_sset(phydev, &ecmd);
  14907. +
  14908. + case ETHTOOL_NWAY_RST:
  14909. + /* if autoneg is off, it's an error */
  14910. + tmp = phy_read(phydev, MII_BMCR);
  14911. + if (tmp & BMCR_ANENABLE) {
  14912. + tmp |= (BMCR_ANRESTART);
  14913. + phy_write(phydev, MII_BMCR, tmp);
  14914. + return 0;
  14915. + }
  14916. + return -EINVAL;
  14917. +
  14918. + case ETHTOOL_GLINK:
  14919. + edata.data = (phy_read(phydev,
  14920. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  14921. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  14922. + return -EFAULT;
  14923. + return 0;
  14924. + }
  14925. +
  14926. + return -EOPNOTSUPP;
  14927. +}
  14928. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  14929. +
  14930. /**
  14931. * phy_mii_ioctl - generic PHY MII ioctl interface
  14932. * @phydev: the phy_device struct
  14933. @@ -351,7 +395,7 @@
  14934. }
  14935. phy_write(phydev, mii_data->reg_num, val);
  14936. -
  14937. +
  14938. if (mii_data->reg_num == MII_BMCR &&
  14939. val & BMCR_RESET &&
  14940. phydev->drv->config_init) {
  14941. @@ -470,7 +514,7 @@
  14942. int idx;
  14943. idx = phy_find_setting(phydev->speed, phydev->duplex);
  14944. -
  14945. +
  14946. idx++;
  14947. idx = phy_find_valid(idx, phydev->supported);
  14948. diff -Nur linux-2.6.37.orig/drivers/net/phy/phy_device.c linux-2.6.37/drivers/net/phy/phy_device.c
  14949. --- linux-2.6.37.orig/drivers/net/phy/phy_device.c 2011-01-05 01:50:19.000000000 +0100
  14950. +++ linux-2.6.37/drivers/net/phy/phy_device.c 2011-01-11 20:27:54.000000000 +0100
  14951. @@ -149,6 +149,19 @@
  14952. }
  14953. EXPORT_SYMBOL(phy_scan_fixups);
  14954. +static int generic_receive_skb(struct sk_buff *skb)
  14955. +{
  14956. + skb->protocol = eth_type_trans(skb, skb->dev);
  14957. + return netif_receive_skb(skb);
  14958. +}
  14959. +
  14960. +static int generic_rx(struct sk_buff *skb)
  14961. +{
  14962. + skb->protocol = eth_type_trans(skb, skb->dev);
  14963. + return netif_rx(skb);
  14964. +}
  14965. +
  14966. +
  14967. static struct phy_device* phy_device_create(struct mii_bus *bus,
  14968. int addr, int phy_id)
  14969. {
  14970. @@ -180,6 +193,8 @@
  14971. dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
  14972. dev->state = PHY_DOWN;
  14973. + dev->netif_receive_skb = &generic_receive_skb;
  14974. + dev->netif_rx = &generic_rx;
  14975. mutex_init(&dev->lock);
  14976. INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
  14977. diff -Nur linux-2.6.37.orig/drivers/spi/Kconfig linux-2.6.37/drivers/spi/Kconfig
  14978. --- linux-2.6.37.orig/drivers/spi/Kconfig 2011-01-05 01:50:19.000000000 +0100
  14979. +++ linux-2.6.37/drivers/spi/Kconfig 2011-01-11 20:25:48.000000000 +0100
  14980. @@ -53,6 +53,13 @@
  14981. comment "SPI Master Controller Drivers"
  14982. +config SPI_AR71XX
  14983. + tristate "Atheros AR71xx SPI Controller"
  14984. + depends on SPI_MASTER && ATHEROS_AR71XX
  14985. + select SPI_BITBANG
  14986. + help
  14987. + This is the SPI contoller driver for Atheros AR71xx.
  14988. +
  14989. config SPI_ATMEL
  14990. tristate "Atmel SPI Controller"
  14991. depends on (ARCH_AT91 || AVR32)
  14992. diff -Nur linux-2.6.37.orig/drivers/spi/Makefile linux-2.6.37/drivers/spi/Makefile
  14993. --- linux-2.6.37.orig/drivers/spi/Makefile 2011-01-05 01:50:19.000000000 +0100
  14994. +++ linux-2.6.37/drivers/spi/Makefile 2011-01-11 20:25:48.000000000 +0100
  14995. @@ -9,6 +9,7 @@
  14996. obj-$(CONFIG_SPI_MASTER) += spi.o
  14997. # SPI master controller drivers (bus)
  14998. +obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
  14999. obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
  15000. obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
  15001. obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
  15002. diff -Nur linux-2.6.37.orig/drivers/spi/ap83_spi.c linux-2.6.37/drivers/spi/ap83_spi.c
  15003. --- linux-2.6.37.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100
  15004. +++ linux-2.6.37/drivers/spi/ap83_spi.c 2011-01-11 20:25:48.000000000 +0100
  15005. @@ -0,0 +1,282 @@
  15006. +/*
  15007. + * Atheros AP83 board specific SPI Controller driver
  15008. + *
  15009. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15010. + *
  15011. + * This program is free software; you can redistribute it and/or modify
  15012. + * it under the terms of the GNU General Public License version 2 as
  15013. + * published by the Free Software Foundation.
  15014. + *
  15015. + */
  15016. +
  15017. +#include <linux/kernel.h>
  15018. +#include <linux/init.h>
  15019. +#include <linux/delay.h>
  15020. +#include <linux/spinlock.h>
  15021. +#include <linux/workqueue.h>
  15022. +#include <linux/platform_device.h>
  15023. +#include <linux/io.h>
  15024. +#include <linux/spi/spi.h>
  15025. +#include <linux/spi/spi_bitbang.h>
  15026. +#include <linux/bitops.h>
  15027. +#include <linux/gpio.h>
  15028. +
  15029. +#include <asm/mach-ar71xx/ar71xx.h>
  15030. +#include <asm/mach-ar71xx/platform.h>
  15031. +
  15032. +#define DRV_DESC "Atheros AP83 board SPI Controller driver"
  15033. +#define DRV_VERSION "0.1.0"
  15034. +#define DRV_NAME "ap83-spi"
  15035. +
  15036. +#define AP83_SPI_CLK_HIGH (1 << 23)
  15037. +#define AP83_SPI_CLK_LOW 0
  15038. +#define AP83_SPI_MOSI_HIGH (1 << 22)
  15039. +#define AP83_SPI_MOSI_LOW 0
  15040. +
  15041. +#define AP83_SPI_GPIO_CS 1
  15042. +#define AP83_SPI_GPIO_MISO 3
  15043. +
  15044. +struct ap83_spi {
  15045. + struct spi_bitbang bitbang;
  15046. + void __iomem *base;
  15047. + u32 addr;
  15048. +
  15049. + struct platform_device *pdev;
  15050. +};
  15051. +
  15052. +static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg)
  15053. +{
  15054. + return __raw_readl(sp->base + reg);
  15055. +}
  15056. +
  15057. +static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi)
  15058. +{
  15059. + return spi_master_get_devdata(spi->master);
  15060. +}
  15061. +
  15062. +static inline void setsck(struct spi_device *spi, int val)
  15063. +{
  15064. + struct ap83_spi *sp = spidev_to_sp(spi);
  15065. +
  15066. + if (val)
  15067. + sp->addr |= AP83_SPI_CLK_HIGH;
  15068. + else
  15069. + sp->addr &= ~AP83_SPI_CLK_HIGH;
  15070. +
  15071. + dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n",
  15072. + sp->addr, (val) ? "HIGH" : "LOW");
  15073. +
  15074. + ap83_spi_rr(sp, sp->addr);
  15075. +}
  15076. +
  15077. +static inline void setmosi(struct spi_device *spi, int val)
  15078. +{
  15079. + struct ap83_spi *sp = spidev_to_sp(spi);
  15080. +
  15081. + if (val)
  15082. + sp->addr |= AP83_SPI_MOSI_HIGH;
  15083. + else
  15084. + sp->addr &= ~AP83_SPI_MOSI_HIGH;
  15085. +
  15086. + dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n",
  15087. + sp->addr, (val) ? "HIGH" : "LOW");
  15088. +
  15089. + ap83_spi_rr(sp, sp->addr);
  15090. +}
  15091. +
  15092. +static inline u32 getmiso(struct spi_device *spi)
  15093. +{
  15094. + u32 ret;
  15095. +
  15096. + ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0;
  15097. + dev_dbg(&spi->dev, "get MISO: %d\n", ret);
  15098. +
  15099. + return ret;
  15100. +}
  15101. +
  15102. +static inline void do_spidelay(struct spi_device *spi, unsigned nsecs)
  15103. +{
  15104. + ndelay(nsecs);
  15105. +}
  15106. +
  15107. +static void ap83_spi_chipselect(struct spi_device *spi, int on)
  15108. +{
  15109. + struct ap83_spi *sp = spidev_to_sp(spi);
  15110. +
  15111. + dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1);
  15112. +
  15113. + if (on) {
  15114. + ar71xx_flash_acquire();
  15115. +
  15116. + sp->addr = 0;
  15117. + ap83_spi_rr(sp, sp->addr);
  15118. +
  15119. + gpio_set_value(AP83_SPI_GPIO_CS, 0);
  15120. + } else {
  15121. + gpio_set_value(AP83_SPI_GPIO_CS, 1);
  15122. + ar71xx_flash_release();
  15123. + }
  15124. +}
  15125. +
  15126. +#define spidelay(nsecs) \
  15127. + do { \
  15128. + /* Steal the spi_device pointer from our caller. \
  15129. + * The bitbang-API should probably get fixed here... */ \
  15130. + do_spidelay(spi, nsecs); \
  15131. + } while (0)
  15132. +
  15133. +#define EXPAND_BITBANG_TXRX
  15134. +#include <linux/spi/spi_bitbang.h>
  15135. +
  15136. +static u32 ap83_spi_txrx_mode0(struct spi_device *spi,
  15137. + unsigned nsecs, u32 word, u8 bits)
  15138. +{
  15139. + dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits);
  15140. + return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
  15141. +}
  15142. +
  15143. +static u32 ap83_spi_txrx_mode1(struct spi_device *spi,
  15144. + unsigned nsecs, u32 word, u8 bits)
  15145. +{
  15146. + dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits);
  15147. + return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
  15148. +}
  15149. +
  15150. +static u32 ap83_spi_txrx_mode2(struct spi_device *spi,
  15151. + unsigned nsecs, u32 word, u8 bits)
  15152. +{
  15153. + dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits);
  15154. + return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
  15155. +}
  15156. +
  15157. +static u32 ap83_spi_txrx_mode3(struct spi_device *spi,
  15158. + unsigned nsecs, u32 word, u8 bits)
  15159. +{
  15160. + dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits);
  15161. + return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
  15162. +}
  15163. +
  15164. +static int ap83_spi_probe(struct platform_device *pdev)
  15165. +{
  15166. + struct spi_master *master;
  15167. + struct ap83_spi *sp;
  15168. + struct ap83_spi_platform_data *pdata;
  15169. + struct resource *r;
  15170. + int ret;
  15171. +
  15172. + ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso");
  15173. + if (ret) {
  15174. + dev_err(&pdev->dev, "gpio request failed for MISO\n");
  15175. + return ret;
  15176. + }
  15177. +
  15178. + ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs");
  15179. + if (ret) {
  15180. + dev_err(&pdev->dev, "gpio request failed for CS\n");
  15181. + goto err_free_miso;
  15182. + }
  15183. +
  15184. + ret = gpio_direction_input(AP83_SPI_GPIO_MISO);
  15185. + if (ret) {
  15186. + dev_err(&pdev->dev, "unable to set direction of MISO\n");
  15187. + goto err_free_cs;
  15188. + }
  15189. +
  15190. + ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0);
  15191. + if (ret) {
  15192. + dev_err(&pdev->dev, "unable to set direction of CS\n");
  15193. + goto err_free_cs;
  15194. + }
  15195. +
  15196. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15197. + if (master == NULL) {
  15198. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15199. + return -ENOMEM;
  15200. + }
  15201. +
  15202. + sp = spi_master_get_devdata(master);
  15203. + platform_set_drvdata(pdev, sp);
  15204. +
  15205. + pdata = pdev->dev.platform_data;
  15206. +
  15207. + sp->bitbang.master = spi_master_get(master);
  15208. + sp->bitbang.chipselect = ap83_spi_chipselect;
  15209. + sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0;
  15210. + sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1;
  15211. + sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2;
  15212. + sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3;
  15213. +
  15214. + sp->bitbang.master->bus_num = pdev->id;
  15215. + sp->bitbang.master->num_chipselect = 1;
  15216. +
  15217. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15218. + if (r == NULL) {
  15219. + ret = -ENOENT;
  15220. + goto err_spi_put;
  15221. + }
  15222. +
  15223. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15224. + if (!sp->base) {
  15225. + ret = -ENXIO;
  15226. + goto err_spi_put;
  15227. + }
  15228. +
  15229. + ret = spi_bitbang_start(&sp->bitbang);
  15230. + if (!ret)
  15231. + goto err_unmap;
  15232. +
  15233. + dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start);
  15234. +
  15235. + return 0;
  15236. +
  15237. + err_unmap:
  15238. + iounmap(sp->base);
  15239. + err_spi_put:
  15240. + platform_set_drvdata(pdev, NULL);
  15241. + spi_master_put(sp->bitbang.master);
  15242. +
  15243. + err_free_cs:
  15244. + gpio_free(AP83_SPI_GPIO_CS);
  15245. + err_free_miso:
  15246. + gpio_free(AP83_SPI_GPIO_MISO);
  15247. + return ret;
  15248. +}
  15249. +
  15250. +static int ap83_spi_remove(struct platform_device *pdev)
  15251. +{
  15252. + struct ap83_spi *sp = platform_get_drvdata(pdev);
  15253. +
  15254. + spi_bitbang_stop(&sp->bitbang);
  15255. + iounmap(sp->base);
  15256. + platform_set_drvdata(pdev, NULL);
  15257. + spi_master_put(sp->bitbang.master);
  15258. +
  15259. + return 0;
  15260. +}
  15261. +
  15262. +static struct platform_driver ap83_spi_drv = {
  15263. + .probe = ap83_spi_probe,
  15264. + .remove = ap83_spi_remove,
  15265. + .driver = {
  15266. + .name = DRV_NAME,
  15267. + .owner = THIS_MODULE,
  15268. + },
  15269. +};
  15270. +
  15271. +static int __init ap83_spi_init(void)
  15272. +{
  15273. + return platform_driver_register(&ap83_spi_drv);
  15274. +}
  15275. +module_init(ap83_spi_init);
  15276. +
  15277. +static void __exit ap83_spi_exit(void)
  15278. +{
  15279. + platform_driver_unregister(&ap83_spi_drv);
  15280. +}
  15281. +module_exit(ap83_spi_exit);
  15282. +
  15283. +MODULE_ALIAS("platform:" DRV_NAME);
  15284. +MODULE_DESCRIPTION(DRV_DESC);
  15285. +MODULE_VERSION(DRV_VERSION);
  15286. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15287. +MODULE_LICENSE("GPL v2");
  15288. diff -Nur linux-2.6.37.orig/drivers/spi/ar71xx_spi.c linux-2.6.37/drivers/spi/ar71xx_spi.c
  15289. --- linux-2.6.37.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100
  15290. +++ linux-2.6.37/drivers/spi/ar71xx_spi.c 2011-01-11 20:25:48.000000000 +0100
  15291. @@ -0,0 +1,283 @@
  15292. +/*
  15293. + * Atheros AR71xx SPI Controller driver
  15294. + *
  15295. + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
  15296. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  15297. + *
  15298. + * This program is free software; you can redistribute it and/or modify
  15299. + * it under the terms of the GNU General Public License version 2 as
  15300. + * published by the Free Software Foundation.
  15301. + *
  15302. + */
  15303. +
  15304. +#include <linux/kernel.h>
  15305. +#include <linux/init.h>
  15306. +#include <linux/delay.h>
  15307. +#include <linux/spinlock.h>
  15308. +#include <linux/workqueue.h>
  15309. +#include <linux/platform_device.h>
  15310. +#include <linux/io.h>
  15311. +#include <linux/spi/spi.h>
  15312. +#include <linux/spi/spi_bitbang.h>
  15313. +#include <linux/bitops.h>
  15314. +
  15315. +#include <asm/mach-ar71xx/ar71xx.h>
  15316. +#include <asm/mach-ar71xx/platform.h>
  15317. +
  15318. +#define DRV_DESC "Atheros AR71xx SPI Controller driver"
  15319. +#define DRV_VERSION "0.2.4"
  15320. +#define DRV_NAME "ar71xx-spi"
  15321. +
  15322. +#undef PER_BIT_READ
  15323. +
  15324. +struct ar71xx_spi {
  15325. + struct spi_bitbang bitbang;
  15326. + u32 ioc_base;
  15327. + u32 reg_ctrl;
  15328. +
  15329. + void __iomem *base;
  15330. +
  15331. + struct platform_device *pdev;
  15332. + u32 (*get_ioc_base)(u8 chip_select, int cs_high,
  15333. + int is_on);
  15334. +};
  15335. +
  15336. +static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15337. +{
  15338. + return __raw_readl(sp->base + reg);
  15339. +}
  15340. +
  15341. +static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15342. +{
  15343. + __raw_writel(val, sp->base + reg);
  15344. +}
  15345. +
  15346. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15347. +{
  15348. + return spi_master_get_devdata(spi->master);
  15349. +}
  15350. +
  15351. +static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
  15352. +{
  15353. + u32 ret;
  15354. +
  15355. + if (is_on == AR71XX_SPI_CS_INACTIVE)
  15356. + ret = SPI_IOC_CS_ALL;
  15357. + else
  15358. + ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select);
  15359. +
  15360. + return ret;
  15361. +}
  15362. +
  15363. +static void ar71xx_spi_chipselect(struct spi_device *spi, int value)
  15364. +{
  15365. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15366. + void __iomem *base = sp->base;
  15367. + u32 ioc_base;
  15368. +
  15369. + switch (value) {
  15370. + case BITBANG_CS_INACTIVE:
  15371. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15372. + (spi->mode & SPI_CS_HIGH) != 0,
  15373. + AR71XX_SPI_CS_INACTIVE);
  15374. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15375. + break;
  15376. +
  15377. + case BITBANG_CS_ACTIVE:
  15378. + ioc_base = sp->get_ioc_base(spi->chip_select,
  15379. + (spi->mode & SPI_CS_HIGH) != 0,
  15380. + AR71XX_SPI_CS_ACTIVE);
  15381. +
  15382. + __raw_writel(ioc_base, base + SPI_REG_IOC);
  15383. + sp->ioc_base = ioc_base;
  15384. + break;
  15385. + }
  15386. +}
  15387. +
  15388. +static void ar71xx_spi_setup_regs(struct spi_device *spi)
  15389. +{
  15390. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15391. +
  15392. + /* enable GPIO mode */
  15393. + ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15394. +
  15395. + /* save CTRL register */
  15396. + sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL);
  15397. +
  15398. + /* TODO: setup speed? */
  15399. + ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15400. +}
  15401. +
  15402. +static void ar71xx_spi_restore_regs(struct spi_device *spi)
  15403. +{
  15404. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15405. +
  15406. + /* restore CTRL register */
  15407. + ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15408. + /* disable GPIO mode */
  15409. + ar71xx_spi_wr(sp, SPI_REG_FS, 0);
  15410. +}
  15411. +
  15412. +static int ar71xx_spi_setup(struct spi_device *spi)
  15413. +{
  15414. + int status;
  15415. +
  15416. + if (spi->bits_per_word > 32)
  15417. + return -EINVAL;
  15418. +
  15419. + if (!spi->controller_state)
  15420. + ar71xx_spi_setup_regs(spi);
  15421. +
  15422. + status = spi_bitbang_setup(spi);
  15423. + if (status && !spi->controller_state)
  15424. + ar71xx_spi_restore_regs(spi);
  15425. +
  15426. + return status;
  15427. +}
  15428. +
  15429. +static void ar71xx_spi_cleanup(struct spi_device *spi)
  15430. +{
  15431. + ar71xx_spi_restore_regs(spi);
  15432. + spi_bitbang_cleanup(spi);
  15433. +}
  15434. +
  15435. +static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15436. + u32 word, u8 bits)
  15437. +{
  15438. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15439. + void __iomem *base = sp->base;
  15440. + u32 ioc = sp->ioc_base;
  15441. + u32 ret;
  15442. +
  15443. + /* clock starts at inactive polarity */
  15444. + for (word <<= (32 - bits); likely(bits); bits--) {
  15445. + u32 out;
  15446. +
  15447. + if (word & (1 << 31))
  15448. + out = ioc | SPI_IOC_DO;
  15449. + else
  15450. + out = ioc & ~SPI_IOC_DO;
  15451. +
  15452. + /* setup MSB (to slave) on trailing edge */
  15453. + __raw_writel(out, base + SPI_REG_IOC);
  15454. +
  15455. + __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC);
  15456. +
  15457. + word <<= 1;
  15458. +
  15459. +#ifdef PER_BIT_READ
  15460. + /* sample MSB (from slave) on leading edge */
  15461. + ret = __raw_readl(base + SPI_REG_RDS);
  15462. + __raw_writel(out, base + SPI_REG_IOC);
  15463. +#endif
  15464. +
  15465. + }
  15466. +
  15467. +#ifndef PER_BIT_READ
  15468. + ret = __raw_readl(base + SPI_REG_RDS);
  15469. +#endif
  15470. + return ret;
  15471. +}
  15472. +
  15473. +static int ar71xx_spi_probe(struct platform_device *pdev)
  15474. +{
  15475. + struct spi_master *master;
  15476. + struct ar71xx_spi *sp;
  15477. + struct ar71xx_spi_platform_data *pdata;
  15478. + struct resource *r;
  15479. + int ret;
  15480. +
  15481. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15482. + if (master == NULL) {
  15483. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15484. + return -ENOMEM;
  15485. + }
  15486. +
  15487. + sp = spi_master_get_devdata(master);
  15488. + platform_set_drvdata(pdev, sp);
  15489. +
  15490. + pdata = pdev->dev.platform_data;
  15491. +
  15492. + master->setup = ar71xx_spi_setup;
  15493. + master->cleanup = ar71xx_spi_cleanup;
  15494. +
  15495. + sp->bitbang.master = spi_master_get(master);
  15496. + sp->bitbang.chipselect = ar71xx_spi_chipselect;
  15497. + sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
  15498. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15499. +
  15500. + sp->get_ioc_base = ar71xx_spi_get_ioc_base;
  15501. + if (pdata) {
  15502. + sp->bitbang.master->bus_num = pdata->bus_num;
  15503. + sp->bitbang.master->num_chipselect = pdata->num_chipselect;
  15504. + if (pdata->get_ioc_base)
  15505. + sp->get_ioc_base = pdata->get_ioc_base;
  15506. + } else {
  15507. + sp->bitbang.master->bus_num = 0;
  15508. + sp->bitbang.master->num_chipselect = 3;
  15509. + }
  15510. +
  15511. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15512. + if (r == NULL) {
  15513. + ret = -ENOENT;
  15514. + goto err1;
  15515. + }
  15516. +
  15517. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15518. + if (!sp->base) {
  15519. + ret = -ENXIO;
  15520. + goto err1;
  15521. + }
  15522. +
  15523. + ret = spi_bitbang_start(&sp->bitbang);
  15524. + if (!ret)
  15525. + return 0;
  15526. +
  15527. + iounmap(sp->base);
  15528. + err1:
  15529. + platform_set_drvdata(pdev, NULL);
  15530. + spi_master_put(sp->bitbang.master);
  15531. +
  15532. + return ret;
  15533. +}
  15534. +
  15535. +static int ar71xx_spi_remove(struct platform_device *pdev)
  15536. +{
  15537. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15538. +
  15539. + spi_bitbang_stop(&sp->bitbang);
  15540. + iounmap(sp->base);
  15541. + platform_set_drvdata(pdev, NULL);
  15542. + spi_master_put(sp->bitbang.master);
  15543. +
  15544. + return 0;
  15545. +}
  15546. +
  15547. +static struct platform_driver ar71xx_spi_drv = {
  15548. + .probe = ar71xx_spi_probe,
  15549. + .remove = ar71xx_spi_remove,
  15550. + .driver = {
  15551. + .name = DRV_NAME,
  15552. + .owner = THIS_MODULE,
  15553. + },
  15554. +};
  15555. +
  15556. +static int __init ar71xx_spi_init(void)
  15557. +{
  15558. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  15559. + return platform_driver_register(&ar71xx_spi_drv);
  15560. +}
  15561. +module_init(ar71xx_spi_init);
  15562. +
  15563. +static void __exit ar71xx_spi_exit(void)
  15564. +{
  15565. + platform_driver_unregister(&ar71xx_spi_drv);
  15566. +}
  15567. +module_exit(ar71xx_spi_exit);
  15568. +
  15569. +MODULE_ALIAS("platform:" DRV_NAME);
  15570. +MODULE_DESCRIPTION(DRV_DESC);
  15571. +MODULE_VERSION(DRV_VERSION);
  15572. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15573. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
  15574. +MODULE_LICENSE("GPL v2");
  15575. diff -Nur linux-2.6.37.orig/drivers/spi/pb44_spi.c linux-2.6.37/drivers/spi/pb44_spi.c
  15576. --- linux-2.6.37.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100
  15577. +++ linux-2.6.37/drivers/spi/pb44_spi.c 2011-01-11 20:25:48.000000000 +0100
  15578. @@ -0,0 +1,299 @@
  15579. +/*
  15580. + * Atheros PB44 board SPI controller driver
  15581. + *
  15582. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15583. + *
  15584. + * This program is free software; you can redistribute it and/or modify
  15585. + * it under the terms of the GNU General Public License version 2 as
  15586. + * published by the Free Software Foundation.
  15587. + *
  15588. + */
  15589. +
  15590. +#include <linux/kernel.h>
  15591. +#include <linux/init.h>
  15592. +#include <linux/delay.h>
  15593. +#include <linux/spinlock.h>
  15594. +#include <linux/workqueue.h>
  15595. +#include <linux/platform_device.h>
  15596. +#include <linux/io.h>
  15597. +#include <linux/spi/spi.h>
  15598. +#include <linux/spi/spi_bitbang.h>
  15599. +#include <linux/bitops.h>
  15600. +#include <linux/gpio.h>
  15601. +
  15602. +#include <asm/mach-ar71xx/ar71xx.h>
  15603. +#include <asm/mach-ar71xx/platform.h>
  15604. +
  15605. +#define DRV_DESC "Atheros PB44 SPI Controller driver"
  15606. +#define DRV_VERSION "0.1.0"
  15607. +#define DRV_NAME "pb44-spi"
  15608. +
  15609. +#undef PER_BIT_READ
  15610. +
  15611. +struct ar71xx_spi {
  15612. + struct spi_bitbang bitbang;
  15613. + u32 ioc_base;
  15614. + u32 reg_ctrl;
  15615. +
  15616. + void __iomem *base;
  15617. +
  15618. + struct platform_device *pdev;
  15619. +};
  15620. +
  15621. +static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg)
  15622. +{
  15623. + return __raw_readl(sp->base + reg);
  15624. +}
  15625. +
  15626. +static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val)
  15627. +{
  15628. + __raw_writel(val, sp->base + reg);
  15629. +}
  15630. +
  15631. +static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi)
  15632. +{
  15633. + return spi_master_get_devdata(spi->master);
  15634. +}
  15635. +
  15636. +static void pb44_spi_chipselect(struct spi_device *spi, int is_active)
  15637. +{
  15638. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15639. + int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
  15640. +
  15641. + if (is_active) {
  15642. + /* set initial clock polarity */
  15643. + if (spi->mode & SPI_CPOL)
  15644. + sp->ioc_base |= SPI_IOC_CLK;
  15645. + else
  15646. + sp->ioc_base &= ~SPI_IOC_CLK;
  15647. +
  15648. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15649. + }
  15650. +
  15651. + if (spi->chip_select) {
  15652. + unsigned long gpio = (unsigned long) spi->controller_data;
  15653. +
  15654. + /* SPI is normally active-low */
  15655. + gpio_set_value(gpio, cs_high);
  15656. + } else {
  15657. + if (cs_high)
  15658. + sp->ioc_base |= SPI_IOC_CS0;
  15659. + else
  15660. + sp->ioc_base &= ~SPI_IOC_CS0;
  15661. +
  15662. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15663. + }
  15664. +
  15665. +}
  15666. +
  15667. +static int pb44_spi_setup_cs(struct spi_device *spi)
  15668. +{
  15669. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15670. +
  15671. + /* enable GPIO mode */
  15672. + pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
  15673. +
  15674. + /* save CTRL register */
  15675. + sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL);
  15676. + sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC);
  15677. +
  15678. + /* TODO: setup speed? */
  15679. + pb44_spi_wr(sp, SPI_REG_CTRL, 0x43);
  15680. +
  15681. + if (spi->chip_select) {
  15682. + unsigned long gpio = (unsigned long) spi->controller_data;
  15683. + int status = 0;
  15684. +
  15685. + status = gpio_request(gpio, dev_name(&spi->dev));
  15686. + if (status)
  15687. + return status;
  15688. +
  15689. + status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
  15690. + if (status) {
  15691. + gpio_free(gpio);
  15692. + return status;
  15693. + }
  15694. + } else {
  15695. + if (spi->mode & SPI_CS_HIGH)
  15696. + sp->ioc_base |= SPI_IOC_CS0;
  15697. + else
  15698. + sp->ioc_base &= ~SPI_IOC_CS0;
  15699. + pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base);
  15700. + }
  15701. +
  15702. + return 0;
  15703. +}
  15704. +
  15705. +static void pb44_spi_cleanup_cs(struct spi_device *spi)
  15706. +{
  15707. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15708. +
  15709. + if (spi->chip_select) {
  15710. + unsigned long gpio = (unsigned long) spi->controller_data;
  15711. + gpio_free(gpio);
  15712. + }
  15713. +
  15714. + /* restore CTRL register */
  15715. + pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
  15716. + /* disable GPIO mode */
  15717. + pb44_spi_wr(sp, SPI_REG_FS, 0);
  15718. +}
  15719. +
  15720. +static int pb44_spi_setup(struct spi_device *spi)
  15721. +{
  15722. + int status = 0;
  15723. +
  15724. + if (spi->bits_per_word > 32)
  15725. + return -EINVAL;
  15726. +
  15727. + if (!spi->controller_state) {
  15728. + status = pb44_spi_setup_cs(spi);
  15729. + if (status)
  15730. + return status;
  15731. + }
  15732. +
  15733. + status = spi_bitbang_setup(spi);
  15734. + if (status && !spi->controller_state)
  15735. + pb44_spi_cleanup_cs(spi);
  15736. +
  15737. + return status;
  15738. +}
  15739. +
  15740. +static void pb44_spi_cleanup(struct spi_device *spi)
  15741. +{
  15742. + pb44_spi_cleanup_cs(spi);
  15743. + spi_bitbang_cleanup(spi);
  15744. +}
  15745. +
  15746. +static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  15747. + u32 word, u8 bits)
  15748. +{
  15749. + struct ar71xx_spi *sp = spidev_to_sp(spi);
  15750. + u32 ioc = sp->ioc_base;
  15751. + u32 ret;
  15752. +
  15753. + /* clock starts at inactive polarity */
  15754. + for (word <<= (32 - bits); likely(bits); bits--) {
  15755. + u32 out;
  15756. +
  15757. + if (word & (1 << 31))
  15758. + out = ioc | SPI_IOC_DO;
  15759. + else
  15760. + out = ioc & ~SPI_IOC_DO;
  15761. +
  15762. + /* setup MSB (to slave) on trailing edge */
  15763. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15764. + pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK);
  15765. +
  15766. + word <<= 1;
  15767. +
  15768. +#ifdef PER_BIT_READ
  15769. + /* sample MSB (from slave) on leading edge */
  15770. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15771. + pb44_spi_wr(sp, SPI_REG_IOC, out);
  15772. +#endif
  15773. + }
  15774. +
  15775. +#ifndef PER_BIT_READ
  15776. + ret = pb44_spi_rr(sp, SPI_REG_RDS);
  15777. +#endif
  15778. + return ret;
  15779. +}
  15780. +
  15781. +static int pb44_spi_probe(struct platform_device *pdev)
  15782. +{
  15783. + struct spi_master *master;
  15784. + struct ar71xx_spi *sp;
  15785. + struct ar71xx_spi_platform_data *pdata;
  15786. + struct resource *r;
  15787. + int ret;
  15788. +
  15789. + master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  15790. + if (master == NULL) {
  15791. + dev_err(&pdev->dev, "failed to allocate spi master\n");
  15792. + return -ENOMEM;
  15793. + }
  15794. +
  15795. + sp = spi_master_get_devdata(master);
  15796. + platform_set_drvdata(pdev, sp);
  15797. +
  15798. + pdata = pdev->dev.platform_data;
  15799. +
  15800. + master->setup = pb44_spi_setup;
  15801. + master->cleanup = pb44_spi_cleanup;
  15802. + if (pdata) {
  15803. + master->bus_num = pdata->bus_num;
  15804. + master->num_chipselect = pdata->num_chipselect;
  15805. + } else {
  15806. + master->bus_num = 0;
  15807. + master->num_chipselect = 1;
  15808. + }
  15809. +
  15810. + sp->bitbang.master = spi_master_get(master);
  15811. + sp->bitbang.chipselect = pb44_spi_chipselect;
  15812. + sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0;
  15813. + sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  15814. + sp->bitbang.flags = SPI_CS_HIGH;
  15815. +
  15816. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  15817. + if (r == NULL) {
  15818. + ret = -ENOENT;
  15819. + goto err1;
  15820. + }
  15821. +
  15822. + sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
  15823. + if (!sp->base) {
  15824. + ret = -ENXIO;
  15825. + goto err1;
  15826. + }
  15827. +
  15828. + ret = spi_bitbang_start(&sp->bitbang);
  15829. + if (!ret)
  15830. + return 0;
  15831. +
  15832. + iounmap(sp->base);
  15833. + err1:
  15834. + platform_set_drvdata(pdev, NULL);
  15835. + spi_master_put(sp->bitbang.master);
  15836. +
  15837. + return ret;
  15838. +}
  15839. +
  15840. +static int pb44_spi_remove(struct platform_device *pdev)
  15841. +{
  15842. + struct ar71xx_spi *sp = platform_get_drvdata(pdev);
  15843. +
  15844. + spi_bitbang_stop(&sp->bitbang);
  15845. + iounmap(sp->base);
  15846. + platform_set_drvdata(pdev, NULL);
  15847. + spi_master_put(sp->bitbang.master);
  15848. +
  15849. + return 0;
  15850. +}
  15851. +
  15852. +static struct platform_driver pb44_spi_drv = {
  15853. + .probe = pb44_spi_probe,
  15854. + .remove = pb44_spi_remove,
  15855. + .driver = {
  15856. + .name = DRV_NAME,
  15857. + .owner = THIS_MODULE,
  15858. + },
  15859. +};
  15860. +
  15861. +static int __init pb44_spi_init(void)
  15862. +{
  15863. + return platform_driver_register(&pb44_spi_drv);
  15864. +}
  15865. +module_init(pb44_spi_init);
  15866. +
  15867. +static void __exit pb44_spi_exit(void)
  15868. +{
  15869. + platform_driver_unregister(&pb44_spi_drv);
  15870. +}
  15871. +module_exit(pb44_spi_exit);
  15872. +
  15873. +MODULE_ALIAS("platform:" DRV_NAME);
  15874. +MODULE_DESCRIPTION(DRV_DESC);
  15875. +MODULE_VERSION(DRV_VERSION);
  15876. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  15877. +MODULE_LICENSE("GPL v2");
  15878. diff -Nur linux-2.6.37.orig/drivers/spi/spi_vsc7385.c linux-2.6.37/drivers/spi/spi_vsc7385.c
  15879. --- linux-2.6.37.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100
  15880. +++ linux-2.6.37/drivers/spi/spi_vsc7385.c 2011-01-11 20:25:48.000000000 +0100
  15881. @@ -0,0 +1,620 @@
  15882. +/*
  15883. + * SPI driver for the Vitesse VSC7385 ethernet switch
  15884. + *
  15885. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  15886. + *
  15887. + * Parts of this file are based on Atheros' 2.6.15 BSP
  15888. + *
  15889. + * This program is free software; you can redistribute it and/or modify it
  15890. + * under the terms of the GNU General Public License version 2 as published
  15891. + * by the Free Software Foundation.
  15892. + */
  15893. +
  15894. +#include <linux/types.h>
  15895. +#include <linux/kernel.h>
  15896. +#include <linux/init.h>
  15897. +#include <linux/module.h>
  15898. +#include <linux/delay.h>
  15899. +#include <linux/device.h>
  15900. +#include <linux/bitops.h>
  15901. +#include <linux/firmware.h>
  15902. +#include <linux/spi/spi.h>
  15903. +#include <linux/spi/vsc7385.h>
  15904. +
  15905. +#define DRV_NAME "spi-vsc7385"
  15906. +#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver"
  15907. +#define DRV_VERSION "0.1.0"
  15908. +
  15909. +#define VSC73XX_BLOCK_MAC 0x1
  15910. +#define VSC73XX_BLOCK_2 0x2
  15911. +#define VSC73XX_BLOCK_MII 0x3
  15912. +#define VSC73XX_BLOCK_4 0x4
  15913. +#define VSC73XX_BLOCK_5 0x5
  15914. +#define VSC73XX_BLOCK_SYSTEM 0x7
  15915. +
  15916. +#define VSC73XX_SUBBLOCK_PORT_0 0
  15917. +#define VSC73XX_SUBBLOCK_PORT_1 1
  15918. +#define VSC73XX_SUBBLOCK_PORT_2 2
  15919. +#define VSC73XX_SUBBLOCK_PORT_3 3
  15920. +#define VSC73XX_SUBBLOCK_PORT_4 4
  15921. +#define VSC73XX_SUBBLOCK_PORT_MAC 6
  15922. +
  15923. +/* MAC Block registers */
  15924. +#define VSC73XX_MAC_CFG 0x0
  15925. +#define VSC73XX_ADVPORTM 0x19
  15926. +#define VSC73XX_RXOCT 0x50
  15927. +#define VSC73XX_TXOCT 0x51
  15928. +#define VSC73XX_C_RX0 0x52
  15929. +#define VSC73XX_C_RX1 0x53
  15930. +#define VSC73XX_C_RX2 0x54
  15931. +#define VSC73XX_C_TX0 0x55
  15932. +#define VSC73XX_C_TX1 0x56
  15933. +#define VSC73XX_C_TX2 0x57
  15934. +#define VSC73XX_C_CFG 0x58
  15935. +
  15936. +/* MAC_CFG register bits */
  15937. +#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31)
  15938. +#define VSC73XX_MAC_CFG_PORT_RST (1 << 29)
  15939. +#define VSC73XX_MAC_CFG_TX_EN (1 << 28)
  15940. +#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27)
  15941. +#define VSC73XX_MAC_CFG_FDX (1 << 18)
  15942. +#define VSC73XX_MAC_CFG_GIGE (1 << 17)
  15943. +#define VSC73XX_MAC_CFG_RX_EN (1 << 16)
  15944. +#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15)
  15945. +#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14)
  15946. +#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13)
  15947. +#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6)
  15948. +#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5)
  15949. +#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4)
  15950. +#define VSC73XX_MAC_CFG_BIT2 (1 << 2)
  15951. +#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3)
  15952. +
  15953. +/* ADVPORTM register bits */
  15954. +#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7)
  15955. +#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6)
  15956. +#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5)
  15957. +#define VSC73XX_ADVPORTM_INV_GTX (1 << 4)
  15958. +#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3)
  15959. +#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2)
  15960. +#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1)
  15961. +#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0)
  15962. +
  15963. +/* MII Block registers */
  15964. +#define VSC73XX_MII_STAT 0x0
  15965. +#define VSC73XX_MII_CMD 0x1
  15966. +#define VSC73XX_MII_DATA 0x2
  15967. +
  15968. +/* System Block registers */
  15969. +#define VSC73XX_ICPU_SIPAD 0x01
  15970. +#define VSC73XX_ICPU_CLOCK_DELAY 0x05
  15971. +#define VSC73XX_ICPU_CTRL 0x10
  15972. +#define VSC73XX_ICPU_ADDR 0x11
  15973. +#define VSC73XX_ICPU_SRAM 0x12
  15974. +#define VSC73XX_ICPU_MBOX_VAL 0x15
  15975. +#define VSC73XX_ICPU_MBOX_SET 0x16
  15976. +#define VSC73XX_ICPU_MBOX_CLR 0x17
  15977. +#define VSC73XX_ICPU_CHIPID 0x18
  15978. +#define VSC73XX_ICPU_GPIO 0x34
  15979. +
  15980. +#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8)
  15981. +#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7)
  15982. +#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3)
  15983. +#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2)
  15984. +#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1)
  15985. +#define VSC73XX_ICPU_CTRL_SRST (1 << 0)
  15986. +
  15987. +#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12
  15988. +#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff
  15989. +#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28
  15990. +#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf
  15991. +#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385
  15992. +#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395
  15993. +
  15994. +#define VSC73XX_CMD_MODE_READ 0
  15995. +#define VSC73XX_CMD_MODE_WRITE 1
  15996. +#define VSC73XX_CMD_MODE_SHIFT 4
  15997. +#define VSC73XX_CMD_BLOCK_SHIFT 5
  15998. +#define VSC73XX_CMD_BLOCK_MASK 0x7
  15999. +#define VSC73XX_CMD_SUBBLOCK_MASK 0xf
  16000. +
  16001. +#define VSC7385_CLOCK_DELAY ((3 << 4) | 3)
  16002. +#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3)
  16003. +
  16004. +#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \
  16005. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  16006. + VSC73XX_ICPU_CTRL_EXT_ACC_EN)
  16007. +
  16008. +#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \
  16009. + VSC73XX_ICPU_CTRL_BOOT_EN | \
  16010. + VSC73XX_ICPU_CTRL_CLK_EN | \
  16011. + VSC73XX_ICPU_CTRL_SRST)
  16012. +
  16013. +#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \
  16014. + VSC73XX_ADVPORTM_EXC_COL_CONT | \
  16015. + VSC73XX_ADVPORTM_EXT_PORT | \
  16016. + VSC73XX_ADVPORTM_INV_GTX | \
  16017. + VSC73XX_ADVPORTM_ENA_GTX | \
  16018. + VSC73XX_ADVPORTM_DDR_MODE | \
  16019. + VSC73XX_ADVPORTM_IO_LOOPBACK | \
  16020. + VSC73XX_ADVPORTM_HOST_LOOPBACK)
  16021. +
  16022. +#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \
  16023. + VSC73XX_ADVPORTM_ENA_GTX | \
  16024. + VSC73XX_ADVPORTM_DDR_MODE)
  16025. +
  16026. +#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \
  16027. + VSC73XX_MAC_CFG_MAC_RX_RST | \
  16028. + VSC73XX_MAC_CFG_MAC_TX_RST)
  16029. +
  16030. +#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \
  16031. + VSC73XX_MAC_CFG_FDX | \
  16032. + VSC73XX_MAC_CFG_GIGE | \
  16033. + VSC73XX_MAC_CFG_RX_EN)
  16034. +
  16035. +#define VSC73XX_RESET_DELAY 100
  16036. +
  16037. +struct vsc7385 {
  16038. + struct spi_device *spi;
  16039. + struct mutex lock;
  16040. + struct vsc7385_platform_data *pdata;
  16041. +};
  16042. +
  16043. +static int vsc7385_is_addr_valid(u8 block, u8 subblock)
  16044. +{
  16045. + switch (block) {
  16046. + case VSC73XX_BLOCK_MAC:
  16047. + switch (subblock) {
  16048. + case 0 ... 4:
  16049. + case 6:
  16050. + return 1;
  16051. + }
  16052. + break;
  16053. +
  16054. + case VSC73XX_BLOCK_2:
  16055. + case VSC73XX_BLOCK_SYSTEM:
  16056. + switch (subblock) {
  16057. + case 0:
  16058. + return 1;
  16059. + }
  16060. + break;
  16061. +
  16062. + case VSC73XX_BLOCK_MII:
  16063. + case VSC73XX_BLOCK_4:
  16064. + case VSC73XX_BLOCK_5:
  16065. + switch (subblock) {
  16066. + case 0 ... 1:
  16067. + return 1;
  16068. + }
  16069. + break;
  16070. + }
  16071. +
  16072. + return 0;
  16073. +}
  16074. +
  16075. +static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock)
  16076. +{
  16077. + u8 ret;
  16078. +
  16079. + ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT;
  16080. + ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT;
  16081. + ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK;
  16082. +
  16083. + return ret;
  16084. +}
  16085. +
  16086. +static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  16087. + u32 *value)
  16088. +{
  16089. + u8 cmd[4];
  16090. + u8 buf[4];
  16091. + struct spi_transfer t[2];
  16092. + struct spi_message m;
  16093. + int err;
  16094. +
  16095. + if (!vsc7385_is_addr_valid(block, subblock))
  16096. + return -EINVAL;
  16097. +
  16098. + spi_message_init(&m);
  16099. +
  16100. + memset(&t, 0, sizeof(t));
  16101. +
  16102. + t[0].tx_buf = cmd;
  16103. + t[0].len = sizeof(cmd);
  16104. + spi_message_add_tail(&t[0], &m);
  16105. +
  16106. + t[1].rx_buf = buf;
  16107. + t[1].len = sizeof(buf);
  16108. + spi_message_add_tail(&t[1], &m);
  16109. +
  16110. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock);
  16111. + cmd[1] = reg;
  16112. + cmd[2] = 0;
  16113. + cmd[3] = 0;
  16114. +
  16115. + mutex_lock(&vsc->lock);
  16116. + err = spi_sync(vsc->spi, &m);
  16117. + mutex_unlock(&vsc->lock);
  16118. +
  16119. + if (err)
  16120. + return err;
  16121. +
  16122. + *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) |
  16123. + (((u32) buf[2]) << 8) | ((u32) buf[3]);
  16124. +
  16125. + return 0;
  16126. +}
  16127. +
  16128. +
  16129. +static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
  16130. + u32 value)
  16131. +{
  16132. + u8 cmd[2];
  16133. + u8 buf[4];
  16134. + struct spi_transfer t[2];
  16135. + struct spi_message m;
  16136. + int err;
  16137. +
  16138. + if (!vsc7385_is_addr_valid(block, subblock))
  16139. + return -EINVAL;
  16140. +
  16141. + spi_message_init(&m);
  16142. +
  16143. + memset(&t, 0, sizeof(t));
  16144. +
  16145. + t[0].tx_buf = cmd;
  16146. + t[0].len = sizeof(cmd);
  16147. + spi_message_add_tail(&t[0], &m);
  16148. +
  16149. + t[1].tx_buf = buf;
  16150. + t[1].len = sizeof(buf);
  16151. + spi_message_add_tail(&t[1], &m);
  16152. +
  16153. + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock);
  16154. + cmd[1] = reg;
  16155. +
  16156. + buf[0] = (value >> 24) & 0xff;
  16157. + buf[1] = (value >> 16) & 0xff;
  16158. + buf[2] = (value >> 8) & 0xff;
  16159. + buf[3] = value & 0xff;
  16160. +
  16161. + mutex_lock(&vsc->lock);
  16162. + err = spi_sync(vsc->spi, &m);
  16163. + mutex_unlock(&vsc->lock);
  16164. +
  16165. + return err;
  16166. +}
  16167. +
  16168. +static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block,
  16169. + u8 subblock, u8 reg, u32 value,
  16170. + u32 read_mask, u32 read_val)
  16171. +{
  16172. + struct spi_device *spi = vsc->spi;
  16173. + u32 t;
  16174. + int err;
  16175. +
  16176. + err = vsc7385_write(vsc, block, subblock, reg, value);
  16177. + if (err)
  16178. + return err;
  16179. +
  16180. + err = vsc7385_read(vsc, block, subblock, reg, &t);
  16181. + if (err)
  16182. + return err;
  16183. +
  16184. + if ((t & read_mask) != read_val) {
  16185. + dev_err(&spi->dev, "register write error\n");
  16186. + return -EIO;
  16187. + }
  16188. +
  16189. + return 0;
  16190. +}
  16191. +
  16192. +static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val)
  16193. +{
  16194. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16195. + VSC73XX_ICPU_CLOCK_DELAY, val);
  16196. +}
  16197. +
  16198. +static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val)
  16199. +{
  16200. + return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16201. + VSC73XX_ICPU_CLOCK_DELAY, val);
  16202. +}
  16203. +
  16204. +static inline int vsc7385_icpu_stop(struct vsc7385 *vsc)
  16205. +{
  16206. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  16207. + VSC73XX_ICPU_CTRL_STOP);
  16208. +}
  16209. +
  16210. +static inline int vsc7385_icpu_start(struct vsc7385 *vsc)
  16211. +{
  16212. + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
  16213. + VSC73XX_ICPU_CTRL_START);
  16214. +}
  16215. +
  16216. +static inline int vsc7385_icpu_reset(struct vsc7385 *vsc)
  16217. +{
  16218. + int rc;
  16219. +
  16220. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR,
  16221. + 0x0000);
  16222. + if (rc)
  16223. + dev_err(&vsc->spi->dev,
  16224. + "could not reset microcode, err=%d\n", rc);
  16225. +
  16226. + return rc;
  16227. +}
  16228. +
  16229. +static int vsc7385_upload_ucode(struct vsc7385 *vsc)
  16230. +{
  16231. + struct spi_device *spi = vsc->spi;
  16232. + const struct firmware *firmware;
  16233. + char *ucode_name;
  16234. + unsigned char *dp;
  16235. + unsigned int curVal;
  16236. + int i;
  16237. + int diffs;
  16238. + int rc;
  16239. +
  16240. + ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name
  16241. + : "vsc7385_ucode.bin";
  16242. + rc = request_firmware(&firmware, ucode_name, &spi->dev);
  16243. + if (rc) {
  16244. + dev_err(&spi->dev, "request_firmware failed, err=%d\n",
  16245. + rc);
  16246. + return rc;
  16247. + }
  16248. +
  16249. + rc = vsc7385_icpu_stop(vsc);
  16250. + if (rc)
  16251. + goto out;
  16252. +
  16253. + rc = vsc7385_icpu_reset(vsc);
  16254. + if (rc)
  16255. + goto out;
  16256. +
  16257. + dev_info(&spi->dev, "uploading microcode...\n");
  16258. +
  16259. + dp = (unsigned char *) firmware->data;
  16260. + for (i = 0; i < firmware->size; i++) {
  16261. + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16262. + VSC73XX_ICPU_SRAM, *dp++);
  16263. + if (rc) {
  16264. + dev_err(&spi->dev, "could not load microcode, err=%d\n",
  16265. + rc);
  16266. + goto out;
  16267. + }
  16268. + }
  16269. +
  16270. + rc = vsc7385_icpu_reset(vsc);
  16271. + if (rc)
  16272. + goto out;
  16273. +
  16274. + dev_info(&spi->dev, "verifying microcode...\n");
  16275. +
  16276. + dp = (unsigned char *) firmware->data;
  16277. + diffs = 0;
  16278. + for (i = 0; i < firmware->size; i++) {
  16279. + rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16280. + VSC73XX_ICPU_SRAM, &curVal);
  16281. + if (rc) {
  16282. + dev_err(&spi->dev, "could not read microcode %d\n",rc);
  16283. + goto out;
  16284. + }
  16285. +
  16286. + if (curVal > 0xff) {
  16287. + dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n",
  16288. + i, *dp, curVal);
  16289. + rc = -EIO;
  16290. + goto out;
  16291. + }
  16292. +
  16293. + if ((curVal & 0xff) != *dp) {
  16294. + diffs++;
  16295. + dev_err(&spi->dev, "verify error: %04x : %02x %02x\n",
  16296. + i, *dp, curVal);
  16297. +
  16298. + if (diffs > 4)
  16299. + break;
  16300. + }
  16301. + dp++;
  16302. + }
  16303. +
  16304. + if (diffs) {
  16305. + dev_err(&spi->dev, "microcode verification failed\n");
  16306. + rc = -EIO;
  16307. + goto out;
  16308. + }
  16309. +
  16310. + dev_info(&spi->dev, "microcode uploaded\n");
  16311. +
  16312. + rc = vsc7385_icpu_start(vsc);
  16313. +
  16314. + out:
  16315. + release_firmware(firmware);
  16316. + return rc;
  16317. +}
  16318. +
  16319. +static int vsc7385_setup(struct vsc7385 *vsc)
  16320. +{
  16321. + struct vsc7385_platform_data *pdata = vsc->pdata;
  16322. + u32 t;
  16323. + int err;
  16324. +
  16325. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16326. + VSC73XX_ICPU_CLOCK_DELAY,
  16327. + VSC7385_CLOCK_DELAY,
  16328. + VSC7385_CLOCK_DELAY_MASK,
  16329. + VSC7385_CLOCK_DELAY);
  16330. + if (err)
  16331. + goto err;
  16332. +
  16333. + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC,
  16334. + VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM,
  16335. + VSC7385_ADVPORTM_INIT,
  16336. + VSC7385_ADVPORTM_MASK,
  16337. + VSC7385_ADVPORTM_INIT);
  16338. + if (err)
  16339. + goto err;
  16340. +
  16341. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16342. + VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET);
  16343. + if (err)
  16344. + goto err;
  16345. +
  16346. + t = VSC73XX_MAC_CFG_INIT;
  16347. + t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg);
  16348. + t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel);
  16349. + if (pdata->mac_cfg.bit2)
  16350. + t |= VSC73XX_MAC_CFG_BIT2;
  16351. +
  16352. + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
  16353. + VSC73XX_MAC_CFG, t);
  16354. + if (err)
  16355. + goto err;
  16356. +
  16357. + return 0;
  16358. +
  16359. + err:
  16360. + return err;
  16361. +}
  16362. +
  16363. +static int vsc7385_detect(struct vsc7385 *vsc)
  16364. +{
  16365. + struct spi_device *spi = vsc->spi;
  16366. + u32 t;
  16367. + u32 id;
  16368. + u32 rev;
  16369. + int err;
  16370. +
  16371. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16372. + VSC73XX_ICPU_MBOX_VAL, &t);
  16373. + if (err) {
  16374. + dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err);
  16375. + return err;
  16376. + }
  16377. +
  16378. + if (t == 0xffffffff) {
  16379. + dev_dbg(&spi->dev, "assert chip reset\n");
  16380. + if (vsc->pdata->reset)
  16381. + vsc->pdata->reset();
  16382. +
  16383. + }
  16384. +
  16385. + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
  16386. + VSC73XX_ICPU_CHIPID, &t);
  16387. + if (err) {
  16388. + dev_err(&spi->dev, "unable to read chip id, err=%d\n", err);
  16389. + return err;
  16390. + }
  16391. +
  16392. + id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK;
  16393. + switch (id) {
  16394. + case VSC73XX_ICPU_CHIPID_ID_7385:
  16395. + case VSC73XX_ICPU_CHIPID_ID_7395:
  16396. + break;
  16397. + default:
  16398. + dev_err(&spi->dev, "unsupported chip, id=%04x\n", id);
  16399. + return -ENODEV;
  16400. + }
  16401. +
  16402. + rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) &
  16403. + VSC73XX_ICPU_CHIPID_REV_MASK;
  16404. + dev_info(&spi->dev, "VSC%04X (rev. %d) switch found \n", id, rev);
  16405. +
  16406. + return 0;
  16407. +}
  16408. +
  16409. +static int __devinit vsc7385_probe(struct spi_device *spi)
  16410. +{
  16411. + struct vsc7385 *vsc;
  16412. + struct vsc7385_platform_data *pdata;
  16413. + int err;
  16414. +
  16415. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
  16416. +
  16417. + pdata = spi->dev.platform_data;
  16418. + if (!pdata) {
  16419. + dev_err(&spi->dev, "no platform data specified\n");
  16420. + return-ENODEV;
  16421. + }
  16422. +
  16423. + vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
  16424. + if (!vsc) {
  16425. + dev_err(&spi->dev, "no memory for private data\n");
  16426. + return-ENOMEM;
  16427. + }
  16428. +
  16429. + mutex_init(&vsc->lock);
  16430. + vsc->pdata = pdata;
  16431. + vsc->spi = spi_dev_get(spi);
  16432. + dev_set_drvdata(&spi->dev, vsc);
  16433. +
  16434. + spi->mode = SPI_MODE_0;
  16435. + spi->bits_per_word = 8;
  16436. + err = spi_setup(spi);
  16437. + if (err) {
  16438. + dev_err(&spi->dev, "spi_setup failed, err=%d \n", err);
  16439. + goto err_drvdata;
  16440. + }
  16441. +
  16442. + err = vsc7385_detect(vsc);
  16443. + if (err) {
  16444. + dev_err(&spi->dev, "no chip found, err=%d \n", err);
  16445. + goto err_drvdata;
  16446. + }
  16447. +
  16448. + err = vsc7385_upload_ucode(vsc);
  16449. + if (err)
  16450. + goto err_drvdata;
  16451. +
  16452. + err = vsc7385_setup(vsc);
  16453. + if (err)
  16454. + goto err_drvdata;
  16455. +
  16456. + return 0;
  16457. +
  16458. + err_drvdata:
  16459. + dev_set_drvdata(&spi->dev, NULL);
  16460. + kfree(vsc);
  16461. + return err;
  16462. +}
  16463. +
  16464. +static int __devexit vsc7385_remove(struct spi_device *spi)
  16465. +{
  16466. + struct vsc7385_data *vsc;
  16467. +
  16468. + vsc = dev_get_drvdata(&spi->dev);
  16469. + dev_set_drvdata(&spi->dev, NULL);
  16470. + kfree(vsc);
  16471. +
  16472. + return 0;
  16473. +}
  16474. +
  16475. +static struct spi_driver vsc7385_driver = {
  16476. + .driver = {
  16477. + .name = DRV_NAME,
  16478. + .bus = &spi_bus_type,
  16479. + .owner = THIS_MODULE,
  16480. + },
  16481. + .probe = vsc7385_probe,
  16482. + .remove = __devexit_p(vsc7385_remove),
  16483. +};
  16484. +
  16485. +static int __init vsc7385_init(void)
  16486. +{
  16487. + return spi_register_driver(&vsc7385_driver);
  16488. +}
  16489. +module_init(vsc7385_init);
  16490. +
  16491. +static void __exit vsc7385_exit(void)
  16492. +{
  16493. + spi_unregister_driver(&vsc7385_driver);
  16494. +}
  16495. +module_exit(vsc7385_exit);
  16496. +
  16497. +MODULE_DESCRIPTION(DRV_DESC);
  16498. +MODULE_VERSION(DRV_VERSION);
  16499. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
  16500. +MODULE_LICENSE("GPL v2");
  16501. +
  16502. diff -Nur linux-2.6.37.orig/drivers/usb/host/Kconfig linux-2.6.37/drivers/usb/host/Kconfig
  16503. --- linux-2.6.37.orig/drivers/usb/host/Kconfig 2011-01-05 01:50:19.000000000 +0100
  16504. +++ linux-2.6.37/drivers/usb/host/Kconfig 2011-01-11 20:25:48.000000000 +0100
  16505. @@ -118,6 +118,13 @@
  16506. config USB_FSL_MPH_DR_OF
  16507. tristate
  16508. +config USB_EHCI_AR71XX
  16509. + bool "USB EHCI support for AR71xx"
  16510. + depends on USB_EHCI_HCD && ATHEROS_AR71XX
  16511. + default y
  16512. + help
  16513. + Support for Atheros AR71xx built-in EHCI controller
  16514. +
  16515. config USB_EHCI_FSL
  16516. bool "Support for Freescale on-chip EHCI USB controller"
  16517. depends on USB_EHCI_HCD && FSL_SOC
  16518. @@ -232,6 +239,13 @@
  16519. Enables support for the on-chip OHCI controller on
  16520. OMAP3 and later chips.
  16521. +config USB_OHCI_AR71XX
  16522. + bool "USB OHCI support for Atheros AR71xx"
  16523. + depends on USB_OHCI_HCD && ATHEROS_AR71XX
  16524. + default y
  16525. + help
  16526. + Support for Atheros AR71xx built-in OHCI controller
  16527. +
  16528. config USB_OHCI_HCD_PPC_SOC
  16529. bool "OHCI support for on-chip PPC USB controller"
  16530. depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
  16531. diff -Nur linux-2.6.37.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.37/drivers/usb/host/ehci-ar71xx.c
  16532. --- linux-2.6.37.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16533. +++ linux-2.6.37/drivers/usb/host/ehci-ar71xx.c 2011-01-11 20:25:48.000000000 +0100
  16534. @@ -0,0 +1,242 @@
  16535. +/*
  16536. + * Bus Glue for Atheros AR71xx built-in EHCI controller.
  16537. + *
  16538. + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
  16539. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16540. + *
  16541. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16542. + * Copyright (C) 2007 Atheros Communications, Inc.
  16543. + *
  16544. + * This program is free software; you can redistribute it and/or modify it
  16545. + * under the terms of the GNU General Public License version 2 as published
  16546. + * by the Free Software Foundation.
  16547. + */
  16548. +
  16549. +#include <linux/platform_device.h>
  16550. +#include <linux/delay.h>
  16551. +
  16552. +#include <asm/mach-ar71xx/platform.h>
  16553. +
  16554. +extern int usb_disabled(void);
  16555. +
  16556. +static int ehci_ar71xx_init(struct usb_hcd *hcd)
  16557. +{
  16558. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16559. + int ret;
  16560. +
  16561. + ehci->caps = hcd->regs;
  16562. + ehci->regs = hcd->regs +
  16563. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16564. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16565. +
  16566. + ehci->sbrn = 0x20;
  16567. + ehci->has_synopsys_hc_bug = 1;
  16568. +
  16569. + ehci_reset(ehci);
  16570. +
  16571. + ret = ehci_init(hcd);
  16572. + if (ret)
  16573. + return ret;
  16574. +
  16575. + ehci_port_power(ehci, 0);
  16576. +
  16577. + return 0;
  16578. +}
  16579. +
  16580. +static int ehci_ar91xx_init(struct usb_hcd *hcd)
  16581. +{
  16582. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  16583. + int ret;
  16584. +
  16585. + ehci->caps = hcd->regs + 0x100;
  16586. + ehci->regs = hcd->regs + 0x100 +
  16587. + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
  16588. + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  16589. +
  16590. + hcd->has_tt = 1;
  16591. + ehci->sbrn = 0x20;
  16592. +
  16593. + ehci_reset(ehci);
  16594. +
  16595. + ret = ehci_init(hcd);
  16596. + if (ret)
  16597. + return ret;
  16598. +
  16599. + ehci_port_power(ehci, 0);
  16600. +
  16601. + return 0;
  16602. +}
  16603. +
  16604. +static int ehci_ar71xx_probe(const struct hc_driver *driver,
  16605. + struct usb_hcd **hcd_out,
  16606. + struct platform_device *pdev)
  16607. +{
  16608. + struct usb_hcd *hcd;
  16609. + struct resource *res;
  16610. + int irq;
  16611. + int ret;
  16612. +
  16613. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16614. + if (!res) {
  16615. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16616. + dev_name(&pdev->dev));
  16617. + return -ENODEV;
  16618. + }
  16619. + irq = res->start;
  16620. +
  16621. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16622. + if (!res) {
  16623. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16624. + dev_name(&pdev->dev));
  16625. + return -ENODEV;
  16626. + }
  16627. +
  16628. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16629. + if (!hcd)
  16630. + return -ENOMEM;
  16631. +
  16632. + hcd->rsrc_start = res->start;
  16633. + hcd->rsrc_len = res->end - res->start + 1;
  16634. +
  16635. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16636. + dev_dbg(&pdev->dev, "controller already in use\n");
  16637. + ret = -EBUSY;
  16638. + goto err_put_hcd;
  16639. + }
  16640. +
  16641. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16642. + if (!hcd->regs) {
  16643. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16644. + ret = -EFAULT;
  16645. + goto err_release_region;
  16646. + }
  16647. +
  16648. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  16649. + if (ret)
  16650. + goto err_iounmap;
  16651. +
  16652. + return 0;
  16653. +
  16654. + err_iounmap:
  16655. + iounmap(hcd->regs);
  16656. +
  16657. + err_release_region:
  16658. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16659. + err_put_hcd:
  16660. + usb_put_hcd(hcd);
  16661. + return ret;
  16662. +}
  16663. +
  16664. +static void ehci_ar71xx_remove(struct usb_hcd *hcd,
  16665. + struct platform_device *pdev)
  16666. +{
  16667. + usb_remove_hcd(hcd);
  16668. + iounmap(hcd->regs);
  16669. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16670. + usb_put_hcd(hcd);
  16671. +}
  16672. +
  16673. +static const struct hc_driver ehci_ar71xx_hc_driver = {
  16674. + .description = hcd_name,
  16675. + .product_desc = "Atheros AR71xx built-in EHCI controller",
  16676. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16677. +
  16678. + .irq = ehci_irq,
  16679. + .flags = HCD_MEMORY | HCD_USB2,
  16680. +
  16681. + .reset = ehci_ar71xx_init,
  16682. + .start = ehci_run,
  16683. + .stop = ehci_stop,
  16684. + .shutdown = ehci_shutdown,
  16685. +
  16686. + .urb_enqueue = ehci_urb_enqueue,
  16687. + .urb_dequeue = ehci_urb_dequeue,
  16688. + .endpoint_disable = ehci_endpoint_disable,
  16689. + .endpoint_reset = ehci_endpoint_reset,
  16690. +
  16691. + .get_frame_number = ehci_get_frame,
  16692. +
  16693. + .hub_status_data = ehci_hub_status_data,
  16694. + .hub_control = ehci_hub_control,
  16695. +#ifdef CONFIG_PM
  16696. + .hub_suspend = ehci_hub_suspend,
  16697. + .hub_resume = ehci_hub_resume,
  16698. +#endif
  16699. + .relinquish_port = ehci_relinquish_port,
  16700. + .port_handed_over = ehci_port_handed_over,
  16701. +
  16702. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16703. +};
  16704. +
  16705. +static const struct hc_driver ehci_ar91xx_hc_driver = {
  16706. + .description = hcd_name,
  16707. + .product_desc = "Atheros AR91xx built-in EHCI controller",
  16708. + .hcd_priv_size = sizeof(struct ehci_hcd),
  16709. + .irq = ehci_irq,
  16710. + .flags = HCD_MEMORY | HCD_USB2,
  16711. +
  16712. + .reset = ehci_ar91xx_init,
  16713. + .start = ehci_run,
  16714. + .stop = ehci_stop,
  16715. + .shutdown = ehci_shutdown,
  16716. +
  16717. + .urb_enqueue = ehci_urb_enqueue,
  16718. + .urb_dequeue = ehci_urb_dequeue,
  16719. + .endpoint_disable = ehci_endpoint_disable,
  16720. + .endpoint_reset = ehci_endpoint_reset,
  16721. +
  16722. + .get_frame_number = ehci_get_frame,
  16723. +
  16724. + .hub_status_data = ehci_hub_status_data,
  16725. + .hub_control = ehci_hub_control,
  16726. +#ifdef CONFIG_PM
  16727. + .hub_suspend = ehci_hub_suspend,
  16728. + .hub_resume = ehci_hub_resume,
  16729. +#endif
  16730. + .relinquish_port = ehci_relinquish_port,
  16731. + .port_handed_over = ehci_port_handed_over,
  16732. +
  16733. + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  16734. +};
  16735. +
  16736. +static int ehci_ar71xx_driver_probe(struct platform_device *pdev)
  16737. +{
  16738. + struct ar71xx_ehci_platform_data *pdata;
  16739. + struct usb_hcd *hcd = NULL;
  16740. + int ret;
  16741. +
  16742. + if (usb_disabled())
  16743. + return -ENODEV;
  16744. +
  16745. + pdata = pdev->dev.platform_data;
  16746. + if (!pdata) {
  16747. + dev_err(&pdev->dev, "no platform data specified for %s\n",
  16748. + dev_name(&pdev->dev));
  16749. + return -ENODEV;
  16750. + }
  16751. +
  16752. + if (pdata->is_ar91xx)
  16753. + ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev);
  16754. + else
  16755. + ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev);
  16756. +
  16757. + return ret;
  16758. +}
  16759. +
  16760. +static int ehci_ar71xx_driver_remove(struct platform_device *pdev)
  16761. +{
  16762. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16763. +
  16764. + ehci_ar71xx_remove(hcd, pdev);
  16765. + return 0;
  16766. +}
  16767. +
  16768. +MODULE_ALIAS("platform:ar71xx-ehci");
  16769. +
  16770. +static struct platform_driver ehci_ar71xx_driver = {
  16771. + .probe = ehci_ar71xx_driver_probe,
  16772. + .remove = ehci_ar71xx_driver_remove,
  16773. + .driver = {
  16774. + .name = "ar71xx-ehci",
  16775. + }
  16776. +};
  16777. diff -Nur linux-2.6.37.orig/drivers/usb/host/ehci-hcd.c linux-2.6.37/drivers/usb/host/ehci-hcd.c
  16778. --- linux-2.6.37.orig/drivers/usb/host/ehci-hcd.c 2011-01-05 01:50:19.000000000 +0100
  16779. +++ linux-2.6.37/drivers/usb/host/ehci-hcd.c 2011-01-11 20:25:48.000000000 +0100
  16780. @@ -1216,6 +1216,11 @@
  16781. #define PLATFORM_DRIVER ehci_octeon_driver
  16782. #endif
  16783. +#ifdef CONFIG_USB_EHCI_AR71XX
  16784. +#include "ehci-ar71xx.c"
  16785. +#define PLATFORM_DRIVER ehci_ar71xx_driver
  16786. +#endif
  16787. +
  16788. #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
  16789. !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
  16790. !defined(XILINX_OF_PLATFORM_DRIVER)
  16791. diff -Nur linux-2.6.37.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.37/drivers/usb/host/ohci-ar71xx.c
  16792. --- linux-2.6.37.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100
  16793. +++ linux-2.6.37/drivers/usb/host/ohci-ar71xx.c 2011-01-11 20:25:48.000000000 +0100
  16794. @@ -0,0 +1,165 @@
  16795. +/*
  16796. + * OHCI HCD (Host Controller Driver) for USB.
  16797. + *
  16798. + * Bus Glue for Atheros AR71xx built-in OHCI controller.
  16799. + *
  16800. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  16801. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  16802. + *
  16803. + * Parts of this file are based on Atheros' 2.6.15 BSP
  16804. + * Copyright (C) 2007 Atheros Communications, Inc.
  16805. + *
  16806. + * This program is free software; you can redistribute it and/or modify it
  16807. + * under the terms of the GNU General Public License version 2 as published
  16808. + * by the Free Software Foundation.
  16809. + */
  16810. +
  16811. +#include <linux/platform_device.h>
  16812. +#include <linux/delay.h>
  16813. +
  16814. +extern int usb_disabled(void);
  16815. +
  16816. +static int usb_hcd_ar71xx_probe(const struct hc_driver *driver,
  16817. + struct platform_device *pdev)
  16818. +{
  16819. + struct usb_hcd *hcd;
  16820. + struct resource *res;
  16821. + int irq;
  16822. + int ret;
  16823. +
  16824. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  16825. + if (!res) {
  16826. + dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
  16827. + dev_name(&pdev->dev));
  16828. + return -ENODEV;
  16829. + }
  16830. + irq = res->start;
  16831. +
  16832. + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  16833. + if (!hcd)
  16834. + return -ENOMEM;
  16835. +
  16836. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  16837. + if (!res) {
  16838. + dev_dbg(&pdev->dev, "no base address specified for %s\n",
  16839. + dev_name(&pdev->dev));
  16840. + ret = -ENODEV;
  16841. + goto err_put_hcd;
  16842. + }
  16843. + hcd->rsrc_start = res->start;
  16844. + hcd->rsrc_len = res->end - res->start + 1;
  16845. +
  16846. + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
  16847. + dev_dbg(&pdev->dev, "controller already in use\n");
  16848. + ret = -EBUSY;
  16849. + goto err_put_hcd;
  16850. + }
  16851. +
  16852. + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
  16853. + if (!hcd->regs) {
  16854. + dev_dbg(&pdev->dev, "error mapping memory\n");
  16855. + ret = -EFAULT;
  16856. + goto err_release_region;
  16857. + }
  16858. +
  16859. + ohci_hcd_init(hcd_to_ohci(hcd));
  16860. +
  16861. + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  16862. + if (ret)
  16863. + goto err_stop_hcd;
  16864. +
  16865. + return 0;
  16866. +
  16867. + err_stop_hcd:
  16868. + iounmap(hcd->regs);
  16869. + err_release_region:
  16870. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16871. + err_put_hcd:
  16872. + usb_put_hcd(hcd);
  16873. + return ret;
  16874. +}
  16875. +
  16876. +void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  16877. +{
  16878. + usb_remove_hcd(hcd);
  16879. + iounmap(hcd->regs);
  16880. + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  16881. + usb_put_hcd(hcd);
  16882. +}
  16883. +
  16884. +static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd)
  16885. +{
  16886. + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  16887. + int ret;
  16888. +
  16889. + ret = ohci_init(ohci);
  16890. + if (ret < 0)
  16891. + return ret;
  16892. +
  16893. + ret = ohci_run(ohci);
  16894. + if (ret < 0)
  16895. + goto err;
  16896. +
  16897. + return 0;
  16898. +
  16899. + err:
  16900. + ohci_stop(hcd);
  16901. + return ret;
  16902. +}
  16903. +
  16904. +static const struct hc_driver ohci_ar71xx_hc_driver = {
  16905. + .description = hcd_name,
  16906. + .product_desc = "Atheros AR71xx built-in OHCI controller",
  16907. + .hcd_priv_size = sizeof(struct ohci_hcd),
  16908. +
  16909. + .irq = ohci_irq,
  16910. + .flags = HCD_USB11 | HCD_MEMORY,
  16911. +
  16912. + .start = ohci_ar71xx_start,
  16913. + .stop = ohci_stop,
  16914. + .shutdown = ohci_shutdown,
  16915. +
  16916. + .urb_enqueue = ohci_urb_enqueue,
  16917. + .urb_dequeue = ohci_urb_dequeue,
  16918. + .endpoint_disable = ohci_endpoint_disable,
  16919. +
  16920. + /*
  16921. + * scheduling support
  16922. + */
  16923. + .get_frame_number = ohci_get_frame,
  16924. +
  16925. + /*
  16926. + * root hub support
  16927. + */
  16928. + .hub_status_data = ohci_hub_status_data,
  16929. + .hub_control = ohci_hub_control,
  16930. + .start_port_reset = ohci_start_port_reset,
  16931. +};
  16932. +
  16933. +static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev)
  16934. +{
  16935. + if (usb_disabled())
  16936. + return -ENODEV;
  16937. +
  16938. + return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev);
  16939. +}
  16940. +
  16941. +static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev)
  16942. +{
  16943. + struct usb_hcd *hcd = platform_get_drvdata(pdev);
  16944. +
  16945. + usb_hcd_ar71xx_remove(hcd, pdev);
  16946. + return 0;
  16947. +}
  16948. +
  16949. +MODULE_ALIAS("platform:ar71xx-ohci");
  16950. +
  16951. +static struct platform_driver ohci_hcd_ar71xx_driver = {
  16952. + .probe = ohci_hcd_ar71xx_drv_probe,
  16953. + .remove = ohci_hcd_ar71xx_drv_remove,
  16954. + .shutdown = usb_hcd_platform_shutdown,
  16955. + .driver = {
  16956. + .name = "ar71xx-ohci",
  16957. + .owner = THIS_MODULE,
  16958. + },
  16959. +};
  16960. diff -Nur linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c linux-2.6.37/drivers/usb/host/ohci-hcd.c
  16961. --- linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c 2011-01-05 01:50:19.000000000 +0100
  16962. +++ linux-2.6.37/drivers/usb/host/ohci-hcd.c 2011-01-11 20:25:48.000000000 +0100
  16963. @@ -1111,6 +1111,11 @@
  16964. #define PLATFORM_DRIVER ohci_octeon_driver
  16965. #endif
  16966. +#ifdef CONFIG_USB_OHCI_AR71XX
  16967. +#include "ohci-ar71xx.c"
  16968. +#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
  16969. +#endif
  16970. +
  16971. #if !defined(PCI_DRIVER) && \
  16972. !defined(PLATFORM_DRIVER) && \
  16973. !defined(OMAP1_PLATFORM_DRIVER) && \
  16974. diff -Nur linux-2.6.37.orig/drivers/watchdog/Kconfig linux-2.6.37/drivers/watchdog/Kconfig
  16975. --- linux-2.6.37.orig/drivers/watchdog/Kconfig 2011-01-05 01:50:19.000000000 +0100
  16976. +++ linux-2.6.37/drivers/watchdog/Kconfig 2011-01-11 20:25:48.000000000 +0100
  16977. @@ -930,6 +930,13 @@
  16978. To compile this driver as a loadable module, choose M here.
  16979. The module will be called bcm63xx_wdt.
  16980. +config AR71XX_WDT
  16981. + tristate "Atheros AR71xx Watchdog Timer"
  16982. + depends on ATHEROS_AR71XX
  16983. + help
  16984. + Hardware driver for the built-in watchdog timer on the Atheros
  16985. + AR71xx SoCs.
  16986. +
  16987. # PARISC Architecture
  16988. # POWERPC Architecture
  16989. diff -Nur linux-2.6.37.orig/drivers/watchdog/Makefile linux-2.6.37/drivers/watchdog/Makefile
  16990. --- linux-2.6.37.orig/drivers/watchdog/Makefile 2011-01-05 01:50:19.000000000 +0100
  16991. +++ linux-2.6.37/drivers/watchdog/Makefile 2011-01-11 20:25:48.000000000 +0100
  16992. @@ -117,6 +117,7 @@
  16993. obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
  16994. obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
  16995. obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
  16996. +obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
  16997. obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
  16998. octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
  16999. diff -Nur linux-2.6.37.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.37/drivers/watchdog/ar71xx_wdt.c
  17000. --- linux-2.6.37.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100
  17001. +++ linux-2.6.37/drivers/watchdog/ar71xx_wdt.c 2011-01-11 20:25:48.000000000 +0100
  17002. @@ -0,0 +1,270 @@
  17003. +/*
  17004. + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer.
  17005. + *
  17006. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  17007. + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  17008. + *
  17009. + * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
  17010. + * Author: Deepak Saxena <dsaxena@plexity.net>
  17011. + * Copyright 2004 (c) MontaVista, Software, Inc.
  17012. + *
  17013. + * which again was based on sa1100 driver,
  17014. + * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
  17015. + *
  17016. + * This program is free software; you can redistribute it and/or modify it
  17017. + * under the terms of the GNU General Public License version 2 as published
  17018. + * by the Free Software Foundation.
  17019. + *
  17020. + */
  17021. +
  17022. +#include <linux/bitops.h>
  17023. +#include <linux/errno.h>
  17024. +#include <linux/fs.h>
  17025. +#include <linux/init.h>
  17026. +#include <linux/kernel.h>
  17027. +#include <linux/miscdevice.h>
  17028. +#include <linux/module.h>
  17029. +#include <linux/moduleparam.h>
  17030. +#include <linux/platform_device.h>
  17031. +#include <linux/types.h>
  17032. +#include <linux/watchdog.h>
  17033. +
  17034. +#include <asm/mach-ar71xx/ar71xx.h>
  17035. +
  17036. +#define DRV_NAME "ar71xx-wdt"
  17037. +#define DRV_DESC "Atheros AR71xx hardware watchdog driver"
  17038. +#define DRV_VERSION "0.1.0"
  17039. +
  17040. +#define WDT_TIMEOUT 15 /* seconds */
  17041. +
  17042. +static int nowayout = WATCHDOG_NOWAYOUT;
  17043. +
  17044. +#ifdef CONFIG_WATCHDOG_NOWAYOUT
  17045. +module_param(nowayout, int, 0);
  17046. +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  17047. + "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  17048. +#endif
  17049. +
  17050. +static unsigned long wdt_flags;
  17051. +
  17052. +#define WDT_FLAGS_BUSY 0
  17053. +#define WDT_FLAGS_EXPECT_CLOSE 1
  17054. +
  17055. +static int wdt_timeout = WDT_TIMEOUT;
  17056. +static int boot_status;
  17057. +static int max_timeout;
  17058. +
  17059. +static void inline ar71xx_wdt_keepalive(void)
  17060. +{
  17061. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout);
  17062. +}
  17063. +
  17064. +static void inline ar71xx_wdt_enable(void)
  17065. +{
  17066. + printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n");
  17067. + ar71xx_wdt_keepalive();
  17068. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
  17069. +}
  17070. +
  17071. +static void inline ar71xx_wdt_disable(void)
  17072. +{
  17073. + printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n");
  17074. + ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
  17075. +}
  17076. +
  17077. +static int ar71xx_wdt_set_timeout(int val)
  17078. +{
  17079. + if (val < 1 || val > max_timeout)
  17080. + return -EINVAL;
  17081. +
  17082. + wdt_timeout = val;
  17083. + ar71xx_wdt_keepalive();
  17084. +
  17085. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout);
  17086. +
  17087. + return 0;
  17088. +}
  17089. +
  17090. +static int ar71xx_wdt_open(struct inode *inode, struct file *file)
  17091. +{
  17092. + if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
  17093. + return -EBUSY;
  17094. +
  17095. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17096. +
  17097. + ar71xx_wdt_enable();
  17098. +
  17099. + return nonseekable_open(inode, file);
  17100. +}
  17101. +
  17102. +static int ar71xx_wdt_release(struct inode *inode, struct file *file)
  17103. +{
  17104. + if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) {
  17105. + ar71xx_wdt_disable();
  17106. + } else {
  17107. + printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, "
  17108. + "watchdog timer will not stop!\n");
  17109. + }
  17110. +
  17111. + clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
  17112. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17113. +
  17114. + return 0;
  17115. +}
  17116. +
  17117. +static ssize_t ar71xx_wdt_write(struct file *file, const char *data,
  17118. + size_t len, loff_t *ppos)
  17119. +{
  17120. + if (len) {
  17121. + if (!nowayout) {
  17122. + size_t i;
  17123. +
  17124. + clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
  17125. +
  17126. + for (i = 0; i != len; i++) {
  17127. + char c;
  17128. +
  17129. + if (get_user(c, data + i))
  17130. + return -EFAULT;
  17131. +
  17132. + if (c == 'V')
  17133. + set_bit(WDT_FLAGS_EXPECT_CLOSE,
  17134. + &wdt_flags);
  17135. + }
  17136. + }
  17137. +
  17138. + ar71xx_wdt_keepalive();
  17139. + }
  17140. +
  17141. + return len;
  17142. +}
  17143. +
  17144. +static struct watchdog_info ar71xx_wdt_info = {
  17145. + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
  17146. + WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
  17147. + .firmware_version = 0,
  17148. + .identity = "AR71XX watchdog",
  17149. +};
  17150. +
  17151. +static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file,
  17152. + unsigned int cmd, unsigned long arg)
  17153. +{
  17154. + int t;
  17155. + int ret;
  17156. +
  17157. + switch (cmd) {
  17158. + case WDIOC_GETSUPPORT:
  17159. + ret = copy_to_user((struct watchdog_info *)arg,
  17160. + &ar71xx_wdt_info,
  17161. + sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0;
  17162. + break;
  17163. +
  17164. + case WDIOC_GETSTATUS:
  17165. + ret = put_user(0, (int *)arg) ? -EFAULT : 0;
  17166. + break;
  17167. +
  17168. + case WDIOC_GETBOOTSTATUS:
  17169. + ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0;
  17170. + break;
  17171. +
  17172. + case WDIOC_KEEPALIVE:
  17173. + ar71xx_wdt_keepalive();
  17174. + ret = 0;
  17175. + break;
  17176. +
  17177. + case WDIOC_SETTIMEOUT:
  17178. + ret = get_user(t, (int *)arg) ? -EFAULT : 0;
  17179. + if (ret)
  17180. + break;
  17181. +
  17182. + ret = ar71xx_wdt_set_timeout(t);
  17183. + if (ret)
  17184. + break;
  17185. +
  17186. + /* fallthrough */
  17187. + case WDIOC_GETTIMEOUT:
  17188. + ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0;
  17189. + break;
  17190. +
  17191. + default:
  17192. + ret = -ENOTTY;
  17193. + break;
  17194. + }
  17195. +
  17196. + return ret;
  17197. +}
  17198. +
  17199. +static const struct file_operations ar71xx_wdt_fops = {
  17200. + .owner = THIS_MODULE,
  17201. + .write = ar71xx_wdt_write,
  17202. + .ioctl = ar71xx_wdt_ioctl,
  17203. + .open = ar71xx_wdt_open,
  17204. + .release = ar71xx_wdt_release,
  17205. +};
  17206. +
  17207. +static struct miscdevice ar71xx_wdt_miscdev = {
  17208. + .minor = WATCHDOG_MINOR,
  17209. + .name = "watchdog",
  17210. + .fops = &ar71xx_wdt_fops,
  17211. +};
  17212. +
  17213. +static int __devinit ar71xx_wdt_probe(struct platform_device *pdev)
  17214. +{
  17215. + int ret;
  17216. +
  17217. + max_timeout = (0xfffffffful / ar71xx_ahb_freq);
  17218. + wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
  17219. +
  17220. + boot_status =
  17221. + (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ?
  17222. + WDIOF_CARDRESET : 0;
  17223. +
  17224. + ret = misc_register(&ar71xx_wdt_miscdev);
  17225. + if (ret)
  17226. + goto err_out;
  17227. +
  17228. + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
  17229. +
  17230. + printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n",
  17231. + wdt_timeout, max_timeout);
  17232. +
  17233. + return 0;
  17234. +
  17235. +err_out:
  17236. + return ret;
  17237. +}
  17238. +
  17239. +static int __devexit ar71xx_wdt_remove(struct platform_device *pdev)
  17240. +{
  17241. + misc_deregister(&ar71xx_wdt_miscdev);
  17242. + return 0;
  17243. +}
  17244. +
  17245. +static struct platform_driver ar71xx_wdt_driver = {
  17246. + .probe = ar71xx_wdt_probe,
  17247. + .remove = __devexit_p(ar71xx_wdt_remove),
  17248. + .driver = {
  17249. + .name = DRV_NAME,
  17250. + .owner = THIS_MODULE,
  17251. + },
  17252. +};
  17253. +
  17254. +static int __init ar71xx_wdt_init(void)
  17255. +{
  17256. + return platform_driver_register(&ar71xx_wdt_driver);
  17257. +}
  17258. +module_init(ar71xx_wdt_init);
  17259. +
  17260. +static void __exit ar71xx_wdt_exit(void)
  17261. +{
  17262. + platform_driver_unregister(&ar71xx_wdt_driver);
  17263. +}
  17264. +module_exit(ar71xx_wdt_exit);
  17265. +
  17266. +MODULE_DESCRIPTION(DRV_DESC);
  17267. +MODULE_VERSION(DRV_VERSION);
  17268. +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
  17269. +MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
  17270. +MODULE_LICENSE("GPL v2");
  17271. +MODULE_ALIAS("platform:" DRV_NAME);
  17272. +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  17273. diff -Nur linux-2.6.37.orig/include/linux/ath9k_platform.h linux-2.6.37/include/linux/ath9k_platform.h
  17274. --- linux-2.6.37.orig/include/linux/ath9k_platform.h 2011-01-05 01:50:19.000000000 +0100
  17275. +++ linux-2.6.37/include/linux/ath9k_platform.h 2011-01-11 20:25:48.000000000 +0100
  17276. @@ -1,19 +1,11 @@
  17277. /*
  17278. - * Copyright (c) 2008 Atheros Communications Inc.
  17279. - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  17280. - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
  17281. + * ath9k platform data defines
  17282. *
  17283. - * Permission to use, copy, modify, and/or distribute this software for any
  17284. - * purpose with or without fee is hereby granted, provided that the above
  17285. - * copyright notice and this permission notice appear in all copies.
  17286. + * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
  17287. *
  17288. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  17289. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  17290. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  17291. - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17292. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17293. - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17294. - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17295. + * This program is free software; you can redistribute it and/or modify it
  17296. + * under the terms of the GNU General Public License version 2 as published
  17297. + * by the Free Software Foundation.
  17298. */
  17299. #ifndef _LINUX_ATH9K_PLATFORM_H
  17300. @@ -23,6 +15,9 @@
  17301. struct ath9k_platform_data {
  17302. u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  17303. + u8 *macaddr;
  17304. +
  17305. + unsigned long quirk_wndr3700:1;
  17306. };
  17307. #endif /* _LINUX_ATH9K_PLATFORM_H */
  17308. diff -Nur linux-2.6.37.orig/include/linux/gpio_buttons.h linux-2.6.37/include/linux/gpio_buttons.h
  17309. --- linux-2.6.37.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100
  17310. +++ linux-2.6.37/include/linux/gpio_buttons.h 2011-01-11 20:25:48.000000000 +0100
  17311. @@ -0,0 +1,33 @@
  17312. +/*
  17313. + * Definitions for the GPIO buttons interface driver
  17314. + *
  17315. + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
  17316. + *
  17317. + * This file was based on: /include/linux/gpio_keys.h
  17318. + * The original gpio_keys.h seems not to have a license.
  17319. + *
  17320. + * This program is free software; you can redistribute it and/or modify
  17321. + * it under the terms of the GNU General Public License version 2 as
  17322. + * published by the Free Software Foundation.
  17323. + *
  17324. + */
  17325. +
  17326. +#ifndef _GPIO_BUTTONS_H_
  17327. +#define _GPIO_BUTTONS_H_
  17328. +
  17329. +struct gpio_button {
  17330. + int gpio; /* GPIO line number */
  17331. + int active_low;
  17332. + char *desc; /* button description */
  17333. + int type; /* input event type (EV_KEY, EV_SW) */
  17334. + int code; /* input event code (KEY_*, SW_*) */
  17335. + int threshold; /* count threshold */
  17336. +};
  17337. +
  17338. +struct gpio_buttons_platform_data {
  17339. + struct gpio_button *buttons;
  17340. + int nbuttons; /* number of buttons */
  17341. + int poll_interval; /* polling interval */
  17342. +};
  17343. +
  17344. +#endif /* _GPIO_BUTTONS_H_ */
  17345. diff -Nur linux-2.6.37.orig/include/linux/gpio_dev.h linux-2.6.37/include/linux/gpio_dev.h
  17346. --- linux-2.6.37.orig/include/linux/gpio_dev.h 1970-01-01 01:00:00.000000000 +0100
  17347. +++ linux-2.6.37/include/linux/gpio_dev.h 2011-01-11 20:25:48.000000000 +0100
  17348. @@ -0,0 +1,11 @@
  17349. +#ifndef _GPIODEV_H__
  17350. +#define _GPIODEV_H__
  17351. +
  17352. +#define IOC_GPIODEV_MAGIC 'B'
  17353. +#define GPIO_GET _IO(IOC_GPIODEV_MAGIC, 10)
  17354. +#define GPIO_SET _IO(IOC_GPIODEV_MAGIC, 11)
  17355. +#define GPIO_CLEAR _IO(IOC_GPIODEV_MAGIC, 12)
  17356. +#define GPIO_DIR_IN _IO(IOC_GPIODEV_MAGIC, 13)
  17357. +#define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 14)
  17358. +
  17359. +#endif
  17360. diff -Nur linux-2.6.37.orig/include/linux/netdevice.h linux-2.6.37/include/linux/netdevice.h
  17361. --- linux-2.6.37.orig/include/linux/netdevice.h 2011-01-05 01:50:19.000000000 +0100
  17362. +++ linux-2.6.37/include/linux/netdevice.h 2011-01-11 20:25:48.000000000 +0100
  17363. @@ -957,6 +957,7 @@
  17364. void *ax25_ptr; /* AX.25 specific data */
  17365. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  17366. assign before registering */
  17367. + void *phy_ptr; /* PHY device specific data */
  17368. /*
  17369. * Cache lines mostly used on receive path (including eth_type_trans())
  17370. diff -Nur linux-2.6.37.orig/include/linux/nxp_74hc153.h linux-2.6.37/include/linux/nxp_74hc153.h
  17371. --- linux-2.6.37.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100
  17372. +++ linux-2.6.37/include/linux/nxp_74hc153.h 2011-01-11 20:25:48.000000000 +0100
  17373. @@ -0,0 +1,24 @@
  17374. +/*
  17375. + * NXP 74HC153 - Dual 4-input multiplexer defines
  17376. + *
  17377. + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
  17378. + *
  17379. + * This program is free software; you can redistribute it and/or modify
  17380. + * it under the terms of the GNU General Public License version 2 as
  17381. + * published by the Free Software Foundation.
  17382. + */
  17383. +
  17384. +#ifndef _NXP_74HC153_H
  17385. +#define _NXP_74HC153_H
  17386. +
  17387. +#define NXP_74HC153_DRIVER_NAME "nxp-74hc153"
  17388. +
  17389. +struct nxp_74hc153_platform_data {
  17390. + unsigned gpio_base;
  17391. + unsigned gpio_pin_s0;
  17392. + unsigned gpio_pin_s1;
  17393. + unsigned gpio_pin_1y;
  17394. + unsigned gpio_pin_2y;
  17395. +};
  17396. +
  17397. +#endif /* _NXP_74HC153_H */
  17398. diff -Nur linux-2.6.37.orig/include/linux/phy.h linux-2.6.37/include/linux/phy.h
  17399. --- linux-2.6.37.orig/include/linux/phy.h 2011-01-05 01:50:19.000000000 +0100
  17400. +++ linux-2.6.37/include/linux/phy.h 2011-01-11 20:25:48.000000000 +0100
  17401. @@ -332,6 +332,20 @@
  17402. void (*adjust_link)(struct net_device *dev);
  17403. void (*adjust_state)(struct net_device *dev);
  17404. +
  17405. + /*
  17406. + * By default these point to the original functions
  17407. + * with the same name. adding them to the phy_device
  17408. + * allows the phy driver to override them for packet
  17409. + * mangling if the ethernet driver supports it
  17410. + * This is required to support some really horrible
  17411. + * switches such as the Marvell 88E6060
  17412. + */
  17413. + int (*netif_receive_skb)(struct sk_buff *skb);
  17414. + int (*netif_rx)(struct sk_buff *skb);
  17415. +
  17416. + /* alignment offset for packets */
  17417. + int pkt_align;
  17418. };
  17419. #define to_phy_device(d) container_of(d, struct phy_device, dev)
  17420. @@ -508,6 +522,7 @@
  17421. void phy_stop_machine(struct phy_device *phydev);
  17422. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17423. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  17424. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  17425. int phy_mii_ioctl(struct phy_device *phydev,
  17426. struct ifreq *ifr, int cmd);
  17427. int phy_start_interrupts(struct phy_device *phydev);
  17428. diff -Nur linux-2.6.37.orig/include/linux/spi/vsc7385.h linux-2.6.37/include/linux/spi/vsc7385.h
  17429. --- linux-2.6.37.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100
  17430. +++ linux-2.6.37/include/linux/spi/vsc7385.h 2011-01-11 20:25:48.000000000 +0100
  17431. @@ -0,0 +1,19 @@
  17432. +/*
  17433. + * Platform data definition for the Vitesse VSC7385 ethernet switch driver
  17434. + *
  17435. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  17436. + *
  17437. + * This program is free software; you can redistribute it and/or modify it
  17438. + * under the terms of the GNU General Public License version 2 as published
  17439. + * by the Free Software Foundation.
  17440. + */
  17441. +
  17442. +struct vsc7385_platform_data {
  17443. + void (* reset)(void);
  17444. + char *ucode_name;
  17445. + struct {
  17446. + u32 tx_ipg:5;
  17447. + u32 bit2:1;
  17448. + u32 clk_sel:3;
  17449. + } mac_cfg;
  17450. +};
  17451. diff -Nur linux-2.6.37.orig/net/dsa/ar7240.c linux-2.6.37/net/dsa/ar7240.c
  17452. --- linux-2.6.37.orig/net/dsa/ar7240.c 1970-01-01 01:00:00.000000000 +0100
  17453. +++ linux-2.6.37/net/dsa/ar7240.c 2011-01-11 20:25:48.000000000 +0100
  17454. @@ -0,0 +1,736 @@
  17455. +/*
  17456. + * DSA driver for the built-in ethernet switch of the Atheros AR7240 SoC
  17457. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  17458. + *
  17459. + * This file was based on:
  17460. + * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
  17461. + * Copyright (c) 2008 Marvell Semiconductor
  17462. + *
  17463. + * This program is free software; you can redistribute it and/or modify it
  17464. + * under the terms of the GNU General Public License version 2 as published
  17465. + * by the Free Software Foundation.
  17466. + *
  17467. + */
  17468. +
  17469. +#include <linux/etherdevice.h>
  17470. +#include <linux/list.h>
  17471. +#include <linux/netdevice.h>
  17472. +#include <linux/phy.h>
  17473. +#include <linux/mii.h>
  17474. +#include <linux/bitops.h>
  17475. +
  17476. +#include "dsa_priv.h"
  17477. +
  17478. +#define BITM(_count) (BIT(_count) - 1)
  17479. +
  17480. +#define AR7240_REG_MASK_CTRL 0x00
  17481. +#define AR7240_MASK_CTRL_REVISION_M BITM(8)
  17482. +#define AR7240_MASK_CTRL_VERSION_M BITM(8)
  17483. +#define AR7240_MASK_CTRL_VERSION_S 8
  17484. +#define AR7240_MASK_CTRL_SOFT_RESET BIT(31)
  17485. +
  17486. +#define AR7240_REG_MAC_ADDR0 0x20
  17487. +#define AR7240_REG_MAC_ADDR1 0x24
  17488. +
  17489. +#define AR7240_REG_FLOOD_MASK 0x2c
  17490. +#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26)
  17491. +
  17492. +#define AR7240_REG_GLOBAL_CTRL 0x30
  17493. +#define AR7240_GLOBAL_CTRL_MTU_M BITM(12)
  17494. +
  17495. +#define AR7240_REG_AT_CTRL 0x5c
  17496. +#define AR7240_AT_CTRL_ARP_EN BIT(20)
  17497. +
  17498. +#define AR7240_REG_TAG_PRIORITY 0x70
  17499. +
  17500. +#define AR7240_REG_SERVICE_TAG 0x74
  17501. +#define AR7240_SERVICE_TAG_M BITM(16)
  17502. +
  17503. +#define AR7240_REG_CPU_PORT 0x78
  17504. +#define AR7240_MIRROR_PORT_S 4
  17505. +#define AR7240_CPU_PORT_EN BIT(8)
  17506. +
  17507. +#define AR7240_REG_MIB_FUNCTION0 0x80
  17508. +#define AR7240_MIB_TIMER_M BITM(16)
  17509. +#define AR7240_MIB_AT_HALF_EN BIT(16)
  17510. +#define AR7240_MIB_BUSY BIT(17)
  17511. +#define AR7240_MIB_FUNC_S 24
  17512. +#define AR7240_MIB_FUNC_NO_OP 0x0
  17513. +#define AR7240_MIB_FUNC_FLUSH 0x1
  17514. +#define AR7240_MIB_FUNC_CAPTURE 0x3
  17515. +
  17516. +#define AR7240_REG_MDIO_CTRL 0x98
  17517. +#define AR7240_MDIO_CTRL_DATA_M BITM(16)
  17518. +#define AR7240_MDIO_CTRL_REG_ADDR_S 16
  17519. +#define AR7240_MDIO_CTRL_PHY_ADDR_S 21
  17520. +#define AR7240_MDIO_CTRL_CMD_WRITE 0
  17521. +#define AR7240_MDIO_CTRL_CMD_READ BIT(27)
  17522. +#define AR7240_MDIO_CTRL_MASTER_EN BIT(30)
  17523. +#define AR7240_MDIO_CTRL_BUSY BIT(31)
  17524. +
  17525. +#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100)
  17526. +
  17527. +#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00)
  17528. +#define AR7240_PORT_STATUS_SPEED_M BITM(2)
  17529. +#define AR7240_PORT_STATUS_SPEED_10 0
  17530. +#define AR7240_PORT_STATUS_SPEED_100 1
  17531. +#define AR7240_PORT_STATUS_SPEED_1000 2
  17532. +#define AR7240_PORT_STATUS_TXMAC BIT(2)
  17533. +#define AR7240_PORT_STATUS_RXMAC BIT(3)
  17534. +#define AR7240_PORT_STATUS_TXFLOW BIT(4)
  17535. +#define AR7240_PORT_STATUS_RXFLOW BIT(5)
  17536. +#define AR7240_PORT_STATUS_DUPLEX BIT(6)
  17537. +#define AR7240_PORT_STATUS_LINK_UP BIT(8)
  17538. +#define AR7240_PORT_STATUS_LINK_AUTO BIT(9)
  17539. +#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10)
  17540. +
  17541. +#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04)
  17542. +#define AR7240_PORT_CTRL_STATE_M BITM(3)
  17543. +#define AR7240_PORT_CTRL_STATE_DISABLED 0
  17544. +#define AR7240_PORT_CTRL_STATE_BLOCK 1
  17545. +#define AR7240_PORT_CTRL_STATE_LISTEN 2
  17546. +#define AR7240_PORT_CTRL_STATE_LEARN 3
  17547. +#define AR7240_PORT_CTRL_STATE_FORWARD 4
  17548. +#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7)
  17549. +#define AR7240_PORT_CTRL_VLAN_MODE_S 8
  17550. +#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0
  17551. +#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1
  17552. +#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2
  17553. +#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3
  17554. +#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10)
  17555. +#define AR7240_PORT_CTRL_HEADER BIT(11)
  17556. +#define AR7240_PORT_CTRL_MAC_LOOP BIT(12)
  17557. +#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13)
  17558. +#define AR7240_PORT_CTRL_LEARN BIT(14)
  17559. +#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15)
  17560. +#define AR7240_PORT_CTRL_MIRROR_TX BIT(16)
  17561. +#define AR7240_PORT_CTRL_MIRROR_RX BIT(17)
  17562. +
  17563. +#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08)
  17564. +
  17565. +#define AR7240_PORT_VLAN_DEFAULT_ID_S 0
  17566. +#define AR7240_PORT_VLAN_DEST_PORTS_S 16
  17567. +
  17568. +#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100)
  17569. +
  17570. +#define AR7240_STATS_RXBROAD 0x00
  17571. +#define AR7240_STATS_RXPAUSE 0x04
  17572. +#define AR7240_STATS_RXMULTI 0x08
  17573. +#define AR7240_STATS_RXFCSERR 0x0c
  17574. +#define AR7240_STATS_RXALIGNERR 0x10
  17575. +#define AR7240_STATS_RXRUNT 0x14
  17576. +#define AR7240_STATS_RXFRAGMENT 0x18
  17577. +#define AR7240_STATS_RX64BYTE 0x1c
  17578. +#define AR7240_STATS_RX128BYTE 0x20
  17579. +#define AR7240_STATS_RX256BYTE 0x24
  17580. +#define AR7240_STATS_RX512BYTE 0x28
  17581. +#define AR7240_STATS_RX1024BYTE 0x2c
  17582. +#define AR7240_STATS_RX1518BYTE 0x30
  17583. +#define AR7240_STATS_RXMAXBYTE 0x34
  17584. +#define AR7240_STATS_RXTOOLONG 0x38
  17585. +#define AR7240_STATS_RXGOODBYTE 0x3c
  17586. +#define AR7240_STATS_RXBADBYTE 0x44
  17587. +#define AR7240_STATS_RXOVERFLOW 0x4c
  17588. +#define AR7240_STATS_FILTERED 0x50
  17589. +#define AR7240_STATS_TXBROAD 0x54
  17590. +#define AR7240_STATS_TXPAUSE 0x58
  17591. +#define AR7240_STATS_TXMULTI 0x5c
  17592. +#define AR7240_STATS_TXUNDERRUN 0x60
  17593. +#define AR7240_STATS_TX64BYTE 0x64
  17594. +#define AR7240_STATS_TX128BYTE 0x68
  17595. +#define AR7240_STATS_TX256BYTE 0x6c
  17596. +#define AR7240_STATS_TX512BYTE 0x70
  17597. +#define AR7240_STATS_TX1024BYTE 0x74
  17598. +#define AR7240_STATS_TX1518BYTE 0x78
  17599. +#define AR7240_STATS_TXMAXBYTE 0x7c
  17600. +#define AR7240_STATS_TXOVERSIZE 0x80
  17601. +#define AR7240_STATS_TXBYTE 0x84
  17602. +#define AR7240_STATS_TXCOLLISION 0x8c
  17603. +#define AR7240_STATS_TXABORTCOL 0x90
  17604. +#define AR7240_STATS_TXMULTICOL 0x94
  17605. +#define AR7240_STATS_TXSINGLECOL 0x98
  17606. +#define AR7240_STATS_TXEXCDEFER 0x9c
  17607. +#define AR7240_STATS_TXDEFER 0xa0
  17608. +#define AR7240_STATS_TXLATECOL 0xa4
  17609. +
  17610. +#define AR7240_PORT_CPU 0
  17611. +#define AR7240_NUM_PORTS 6
  17612. +#define AR7240_NUM_PHYS 5
  17613. +
  17614. +#define AR7240_PHY_ID1 0x004d
  17615. +#define AR7240_PHY_ID2 0xd041
  17616. +
  17617. +#define AR7240_PORT_MASK(_port) BIT((_port))
  17618. +#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS)
  17619. +#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port)))
  17620. +
  17621. +struct ar7240sw {
  17622. + struct mii_bus *mii_bus;
  17623. + struct mutex reg_mutex;
  17624. + struct mutex stats_mutex;
  17625. +};
  17626. +
  17627. +struct ar7240sw_hw_stat {
  17628. + char string[ETH_GSTRING_LEN];
  17629. + int sizeof_stat;
  17630. + int reg;
  17631. +};
  17632. +
  17633. +static inline struct ar7240sw *dsa_to_ar7240sw(struct dsa_switch *ds)
  17634. +{
  17635. + return (struct ar7240sw *)(ds + 1);
  17636. +}
  17637. +
  17638. +static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
  17639. +{
  17640. + as->mii_bus = mii;
  17641. + mutex_init(&as->reg_mutex);
  17642. + mutex_init(&as->stats_mutex);
  17643. +}
  17644. +
  17645. +static inline u16 mk_phy_addr(u32 reg)
  17646. +{
  17647. + return (0x17 & ((reg >> 4) | 0x10));
  17648. +}
  17649. +
  17650. +static inline u16 mk_phy_reg(u32 reg)
  17651. +{
  17652. + return ((reg << 1) & 0x1e);
  17653. +}
  17654. +
  17655. +static inline u16 mk_high_addr(u32 reg)
  17656. +{
  17657. + return ((reg >> 7) & 0x1ff);
  17658. +}
  17659. +
  17660. +static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg)
  17661. +{
  17662. + struct mii_bus *mii = as->mii_bus;
  17663. + u16 phy_addr;
  17664. + u16 phy_reg;
  17665. + u32 hi, lo;
  17666. +
  17667. + reg = (reg & 0xfffffffc) >> 2;
  17668. +
  17669. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17670. +
  17671. + phy_addr = mk_phy_addr(reg);
  17672. + phy_reg = mk_phy_reg(reg);
  17673. +
  17674. + lo = (u32) mdiobus_read(mii, phy_addr, phy_reg);
  17675. + hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1);
  17676. +
  17677. + return ((hi << 16) | lo);
  17678. +}
  17679. +
  17680. +static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val)
  17681. +{
  17682. + struct mii_bus *mii = as->mii_bus;
  17683. + u16 phy_addr;
  17684. + u16 phy_reg;
  17685. +
  17686. + reg = (reg & 0xfffffffc) >> 2;
  17687. +
  17688. + mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
  17689. +
  17690. + phy_addr = mk_phy_addr(reg);
  17691. + phy_reg = mk_phy_reg(reg);
  17692. +
  17693. + mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16));
  17694. + mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff));
  17695. +}
  17696. +
  17697. +static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr)
  17698. +{
  17699. + u32 ret;
  17700. +
  17701. + mutex_lock(&as->reg_mutex);
  17702. + ret = __ar7240sw_reg_read(as, reg_addr);
  17703. + mutex_unlock(&as->reg_mutex);
  17704. +
  17705. + return ret;
  17706. +}
  17707. +
  17708. +static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val)
  17709. +{
  17710. + mutex_lock(&as->reg_mutex);
  17711. + __ar7240sw_reg_write(as, reg_addr, reg_val);
  17712. + mutex_unlock(&as->reg_mutex);
  17713. +}
  17714. +
  17715. +static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val)
  17716. +{
  17717. + u32 t;
  17718. +
  17719. + mutex_lock(&as->reg_mutex);
  17720. + t = __ar7240sw_reg_read(as, reg);
  17721. + t &= ~mask;
  17722. + t |= val;
  17723. + __ar7240sw_reg_write(as, reg, t);
  17724. + mutex_unlock(&as->reg_mutex);
  17725. +
  17726. + return t;
  17727. +}
  17728. +
  17729. +static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val)
  17730. +{
  17731. + u32 t;
  17732. +
  17733. + mutex_lock(&as->reg_mutex);
  17734. + t = __ar7240sw_reg_read(as, reg);
  17735. + t |= val;
  17736. + __ar7240sw_reg_write(as, reg, t);
  17737. + mutex_unlock(&as->reg_mutex);
  17738. +}
  17739. +
  17740. +static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
  17741. + unsigned timeout)
  17742. +{
  17743. + int i;
  17744. +
  17745. + for (i = 0; i < timeout; i++) {
  17746. + u32 t;
  17747. +
  17748. + t = ar7240sw_reg_read(as, reg);
  17749. + if ((t & mask) == val)
  17750. + return 0;
  17751. +
  17752. + msleep(1);
  17753. + }
  17754. +
  17755. + return -ETIMEDOUT;
  17756. +}
  17757. +
  17758. +static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr,
  17759. + unsigned reg_addr)
  17760. +{
  17761. + u32 t;
  17762. + int err;
  17763. +
  17764. + if (phy_addr >= AR7240_NUM_PHYS)
  17765. + return 0xffff;
  17766. +
  17767. + t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17768. + (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17769. + AR7240_MDIO_CTRL_MASTER_EN |
  17770. + AR7240_MDIO_CTRL_BUSY |
  17771. + AR7240_MDIO_CTRL_CMD_READ;
  17772. +
  17773. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17774. + err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17775. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17776. + if (err)
  17777. + return 0xffff;
  17778. +
  17779. + t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL);
  17780. + return (t & AR7240_MDIO_CTRL_DATA_M);
  17781. +}
  17782. +
  17783. +static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
  17784. + unsigned reg_addr, u16 reg_val)
  17785. +{
  17786. + u32 t;
  17787. + int ret;
  17788. +
  17789. + if (phy_addr >= AR7240_NUM_PHYS)
  17790. + return -EINVAL;
  17791. +
  17792. + t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
  17793. + (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
  17794. + AR7240_MDIO_CTRL_MASTER_EN |
  17795. + AR7240_MDIO_CTRL_BUSY |
  17796. + AR7240_MDIO_CTRL_CMD_WRITE |
  17797. + reg_val;
  17798. +
  17799. + ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
  17800. + ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
  17801. + AR7240_MDIO_CTRL_BUSY, 0, 5);
  17802. + return ret;
  17803. +}
  17804. +
  17805. +static int ar7240sw_capture_stats(struct ar7240sw *as)
  17806. +{
  17807. + int ret;
  17808. +
  17809. + /* Capture the hardware statistics for all ports */
  17810. + ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0,
  17811. + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
  17812. +
  17813. + /* Wait for the capturing to complete. */
  17814. + ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0,
  17815. + AR7240_MIB_BUSY, 0, 10);
  17816. + return ret;
  17817. +}
  17818. +
  17819. +static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
  17820. +{
  17821. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port),
  17822. + AR7240_PORT_CTRL_STATE_DISABLED);
  17823. +}
  17824. +
  17825. +static int ar7240sw_reset(struct ar7240sw *as)
  17826. +{
  17827. + int ret;
  17828. + int i;
  17829. +
  17830. + /* Set all ports to disabled state. */
  17831. + for (i = 0; i < AR7240_NUM_PORTS; i++)
  17832. + ar7240sw_disable_port(as, i);
  17833. +
  17834. + /* Wait for transmit queues to drain. */
  17835. + msleep(2);
  17836. +
  17837. + /* Reset the switch. */
  17838. + ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL,
  17839. + AR7240_MASK_CTRL_SOFT_RESET);
  17840. +
  17841. + ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL,
  17842. + AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
  17843. + return ret;
  17844. +}
  17845. +
  17846. +static void ar7240sw_setup(struct ar7240sw *as)
  17847. +{
  17848. + /* Enable CPU port, and disable mirror port */
  17849. + ar7240sw_reg_write(as, AR7240_REG_CPU_PORT,
  17850. + AR7240_CPU_PORT_EN |
  17851. + (15 << AR7240_MIRROR_PORT_S));
  17852. +
  17853. + /* Setup TAG priority mapping */
  17854. + ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50);
  17855. +
  17856. + /* Enable ARP frame acknowledge */
  17857. + ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
  17858. +
  17859. + /* Enable Broadcast frames transmitted to the CPU */
  17860. + ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK,
  17861. + AR7240_FLOOD_MASK_BROAD_TO_CPU);
  17862. +
  17863. + /* setup MTU */
  17864. + ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
  17865. + 1536);
  17866. +
  17867. + /* setup Service TAG */
  17868. + ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M,
  17869. + ETH_P_QINQ);
  17870. +}
  17871. +
  17872. +static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port)
  17873. +{
  17874. + u32 ctrl;
  17875. + u32 dest_ports;
  17876. + u32 vlan;
  17877. +
  17878. + ctrl = AR7240_PORT_CTRL_STATE_FORWARD;
  17879. +
  17880. + if (port == AR7240_PORT_CPU) {
  17881. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17882. + AR7240_PORT_STATUS_SPEED_1000 |
  17883. + AR7240_PORT_STATUS_TXFLOW |
  17884. + AR7240_PORT_STATUS_RXFLOW |
  17885. + AR7240_PORT_STATUS_TXMAC |
  17886. + AR7240_PORT_STATUS_RXMAC |
  17887. + AR7240_PORT_STATUS_DUPLEX);
  17888. +
  17889. + /* allow the CPU port to talk to each of the 'real' ports */
  17890. + dest_ports = AR7240_PORT_MASK_BUT(port);
  17891. +
  17892. + /* remove service tag from ingress frames */
  17893. + ctrl |= AR7240_PORT_CTRL_DOUBLE_TAG;
  17894. + } else {
  17895. + ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
  17896. + AR7240_PORT_STATUS_LINK_AUTO);
  17897. +
  17898. + /*
  17899. + * allow each of the 'real' ports to only talk to the CPU
  17900. + * port.
  17901. + */
  17902. + dest_ports = AR7240_PORT_MASK(port) |
  17903. + AR7240_PORT_MASK(AR7240_PORT_CPU);
  17904. +
  17905. + /* add service tag to egress frames */
  17906. + ctrl |= (AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG <<
  17907. + AR7240_PORT_CTRL_VLAN_MODE_S);
  17908. + }
  17909. +
  17910. + /* set default VID and and destination ports for this VLAN */
  17911. + vlan = port;
  17912. + vlan |= (dest_ports << AR7240_PORT_VLAN_DEST_PORTS_S);
  17913. +
  17914. + ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl);
  17915. + ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan);
  17916. +}
  17917. +
  17918. +static char *ar7240_dsa_probe(struct mii_bus *mii, int sw_addr)
  17919. +{
  17920. + struct ar7240sw as;
  17921. + u32 ctrl;
  17922. + u16 phy_id1;
  17923. + u16 phy_id2;
  17924. + u8 ver;
  17925. +
  17926. + ar7240sw_init(&as, mii);
  17927. +
  17928. + ctrl = ar7240sw_reg_read(&as, AR7240_REG_MASK_CTRL);
  17929. +
  17930. + ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
  17931. + if (ver != 1) {
  17932. + pr_err("ar7240_dsa: unsupported chip, ctrl=%08x\n", ctrl);
  17933. + return NULL;
  17934. + }
  17935. +
  17936. + phy_id1 = ar7240sw_phy_read(&as, 0, MII_PHYSID1);
  17937. + phy_id2 = ar7240sw_phy_read(&as, 0, MII_PHYSID2);
  17938. + if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
  17939. + pr_err("ar7240_dsa: unknown phy id '%04x:%04x'\n",
  17940. + phy_id1, phy_id2);
  17941. + return NULL;
  17942. + }
  17943. +
  17944. + return "Atheros AR7240 built-in";
  17945. +}
  17946. +
  17947. +static int ar7240_dsa_setup(struct dsa_switch *ds)
  17948. +{
  17949. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17950. + int i;
  17951. + int ret;
  17952. +
  17953. + ar7240sw_init(as, ds->master_mii_bus);
  17954. +
  17955. + ret = ar7240sw_reset(as);
  17956. + if (ret)
  17957. + return ret;
  17958. +
  17959. + ar7240sw_setup(as);
  17960. +
  17961. + for (i = 0; i < AR7240_NUM_PORTS; i++) {
  17962. + if (dsa_is_cpu_port(ds, i) || (ds->phys_port_mask & (1 << i)))
  17963. + ar7240sw_setup_port(as, i);
  17964. + else
  17965. + ar7240sw_disable_port(as, i);
  17966. + }
  17967. +
  17968. + return 0;
  17969. +}
  17970. +
  17971. +static int ar7240_dsa_set_addr(struct dsa_switch *ds, u8 *addr)
  17972. +{
  17973. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17974. + u32 t;
  17975. +
  17976. + t = (addr[4] << 8) | addr[5];
  17977. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
  17978. +
  17979. + t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
  17980. + ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR1, t);
  17981. +
  17982. + return 0;
  17983. +}
  17984. +
  17985. +static int ar7240_iort_to_phy_addr(int port)
  17986. +{
  17987. + if (port > 0 && port < AR7240_NUM_PORTS)
  17988. + return port - 1;
  17989. +
  17990. + return -EINVAL;
  17991. +}
  17992. +
  17993. +static int ar7240_dsa_phy_read(struct dsa_switch *ds, int port, int regnum)
  17994. +{
  17995. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  17996. + int phy_addr;
  17997. +
  17998. + phy_addr = ar7240_iort_to_phy_addr(port);
  17999. + if (phy_addr < 0)
  18000. + return 0xffff;
  18001. +
  18002. + return ar7240sw_phy_read(as, phy_addr, regnum);
  18003. +}
  18004. +
  18005. +static int ar7240_dsa_phy_write(struct dsa_switch *ds, int port, int regnum,
  18006. + u16 val)
  18007. +{
  18008. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18009. + int phy_addr;
  18010. +
  18011. + phy_addr = ar7240_iort_to_phy_addr(port);
  18012. + if (phy_addr < 0)
  18013. + return 0xffff;
  18014. +
  18015. + return ar7240sw_phy_write(as, phy_addr, regnum, val);
  18016. +}
  18017. +
  18018. +static const char *ar7240sw_speed_str(unsigned speed)
  18019. +{
  18020. + switch (speed) {
  18021. + case AR7240_PORT_STATUS_SPEED_10:
  18022. + return "10";
  18023. + case AR7240_PORT_STATUS_SPEED_100:
  18024. + return "100";
  18025. + case AR7240_PORT_STATUS_SPEED_1000:
  18026. + return "1000";
  18027. + }
  18028. +
  18029. + return "????";
  18030. +}
  18031. +
  18032. +static void ar7240_dsa_poll_link(struct dsa_switch *ds)
  18033. +{
  18034. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18035. + int i;
  18036. +
  18037. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  18038. + struct net_device *dev;
  18039. + u32 status;
  18040. + int link;
  18041. + unsigned speed;
  18042. + int duplex;
  18043. +
  18044. + dev = ds->ports[i];
  18045. + if (dev == NULL)
  18046. + continue;
  18047. +
  18048. + link = 0;
  18049. + if (dev->flags & IFF_UP) {
  18050. + status = ar7240sw_reg_read(as,
  18051. + AR7240_REG_PORT_STATUS(i));
  18052. + link = !!(status & AR7240_PORT_STATUS_LINK_UP);
  18053. + }
  18054. +
  18055. + if (!link) {
  18056. + if (netif_carrier_ok(dev)) {
  18057. + pr_info("%s: link down\n", dev->name);
  18058. + netif_carrier_off(dev);
  18059. + }
  18060. + continue;
  18061. + }
  18062. +
  18063. + speed = (status & AR7240_PORT_STATUS_SPEED_M);
  18064. + duplex = (status & AR7240_PORT_STATUS_DUPLEX) ? 1 : 0;
  18065. + if (!netif_carrier_ok(dev)) {
  18066. + pr_info("%s: link up, %sMb/s, %s duplex",
  18067. + dev->name,
  18068. + ar7240sw_speed_str(speed),
  18069. + duplex ? "full" : "half");
  18070. + netif_carrier_on(dev);
  18071. + }
  18072. + }
  18073. +}
  18074. +
  18075. +static const struct ar7240sw_hw_stat ar7240_hw_stats[] = {
  18076. + { "rx_broadcast" , 4, AR7240_STATS_RXBROAD, },
  18077. + { "rx_pause" , 4, AR7240_STATS_RXPAUSE, },
  18078. + { "rx_multicast" , 4, AR7240_STATS_RXMULTI, },
  18079. + { "rx_fcs_error" , 4, AR7240_STATS_RXFCSERR, },
  18080. + { "rx_align_error" , 4, AR7240_STATS_RXALIGNERR, },
  18081. + { "rx_undersize" , 4, AR7240_STATS_RXRUNT, },
  18082. + { "rx_fragments" , 4, AR7240_STATS_RXFRAGMENT, },
  18083. + { "rx_64bytes" , 4, AR7240_STATS_RX64BYTE, },
  18084. + { "rx_65_127bytes" , 4, AR7240_STATS_RX128BYTE, },
  18085. + { "rx_128_255bytes" , 4, AR7240_STATS_RX256BYTE, },
  18086. + { "rx_256_511bytes" , 4, AR7240_STATS_RX512BYTE, },
  18087. + { "rx_512_1023bytes" , 4, AR7240_STATS_RX1024BYTE, },
  18088. + { "rx_1024_1518bytes" , 4, AR7240_STATS_RX1518BYTE, },
  18089. + { "rx_1519_max_bytes" , 4, AR7240_STATS_RXMAXBYTE, },
  18090. + { "rx_oversize" , 4, AR7240_STATS_RXTOOLONG, },
  18091. + { "rx_good_bytes" , 8, AR7240_STATS_RXGOODBYTE, },
  18092. + { "rx_bad_bytes" , 8, AR7240_STATS_RXBADBYTE, },
  18093. + { "rx_overflow" , 4, AR7240_STATS_RXOVERFLOW, },
  18094. + { "filtered" , 4, AR7240_STATS_FILTERED, },
  18095. + { "tx_broadcast" , 4, AR7240_STATS_TXBROAD, },
  18096. + { "tx_pause" , 4, AR7240_STATS_TXPAUSE, },
  18097. + { "tx_multicast" , 4, AR7240_STATS_TXMULTI, },
  18098. + { "tx_underrun" , 4, AR7240_STATS_TXUNDERRUN, },
  18099. + { "tx_64bytes" , 4, AR7240_STATS_TX64BYTE, },
  18100. + { "tx_65_127bytes" , 4, AR7240_STATS_TX128BYTE, },
  18101. + { "tx_128_255bytes" , 4, AR7240_STATS_TX256BYTE, },
  18102. + { "tx_256_511bytes" , 4, AR7240_STATS_TX512BYTE, },
  18103. + { "tx_512_1023bytes" , 4, AR7240_STATS_TX1024BYTE, },
  18104. + { "tx_1024_1518bytes" , 4, AR7240_STATS_TX1518BYTE, },
  18105. + { "tx_1519_max_bytes" , 4, AR7240_STATS_TXMAXBYTE, },
  18106. + { "tx_oversize" , 4, AR7240_STATS_TXOVERSIZE, },
  18107. + { "tx_bytes" , 8, AR7240_STATS_TXBYTE, },
  18108. + { "tx_collisions" , 4, AR7240_STATS_TXCOLLISION, },
  18109. + { "tx_abort_collisions" , 4, AR7240_STATS_TXABORTCOL, },
  18110. + { "tx_multi_collisions" , 4, AR7240_STATS_TXMULTICOL, },
  18111. + { "tx_single_collisions", 4, AR7240_STATS_TXSINGLECOL, },
  18112. + { "tx_excessive_deferred", 4, AR7240_STATS_TXEXCDEFER, },
  18113. + { "tx_deferred" , 4, AR7240_STATS_TXDEFER, },
  18114. + { "tx_late_collisions" , 4, AR7240_STATS_TXLATECOL, },
  18115. +};
  18116. +
  18117. +static void ar7240_dsa_get_strings(struct dsa_switch *ds, int port,
  18118. + uint8_t *data)
  18119. +{
  18120. + int i;
  18121. +
  18122. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  18123. + memcpy(data + i * ETH_GSTRING_LEN,
  18124. + ar7240_hw_stats[i].string, ETH_GSTRING_LEN);
  18125. + }
  18126. +}
  18127. +
  18128. +static void ar7240_dsa_get_ethtool_stats(struct dsa_switch *ds, int port,
  18129. + uint64_t *data)
  18130. +{
  18131. + struct ar7240sw *as = dsa_to_ar7240sw(ds);
  18132. + int err;
  18133. + int i;
  18134. +
  18135. + mutex_lock(&as->stats_mutex);
  18136. +
  18137. + err = ar7240sw_capture_stats(as);
  18138. + if (err)
  18139. + goto unlock;
  18140. +
  18141. + for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
  18142. + const struct ar7240sw_hw_stat *s = &ar7240_hw_stats[i];
  18143. + u32 reg = AR7240_REG_STATS_BASE(port);
  18144. + u32 low;
  18145. + u32 high;
  18146. +
  18147. + low = ar7240sw_reg_read(as, reg + s->reg);
  18148. + if (s->sizeof_stat == 8)
  18149. + high = ar7240sw_reg_read(as, reg + s->reg);
  18150. + else
  18151. + high = 0;
  18152. +
  18153. + data[i] = (((u64) high) << 32) | low;
  18154. + }
  18155. +
  18156. + unlock:
  18157. + mutex_unlock(&as->stats_mutex);
  18158. +}
  18159. +
  18160. +static int ar7240_dsa_get_sset_count(struct dsa_switch *ds)
  18161. +{
  18162. + return ARRAY_SIZE(ar7240_hw_stats);
  18163. +}
  18164. +
  18165. +static struct dsa_switch_driver ar7240_dsa_driver = {
  18166. + .tag_protocol = htons(ETH_P_QINQ),
  18167. + .priv_size = sizeof(struct ar7240sw),
  18168. + .probe = ar7240_dsa_probe,
  18169. + .setup = ar7240_dsa_setup,
  18170. + .set_addr = ar7240_dsa_set_addr,
  18171. + .phy_read = ar7240_dsa_phy_read,
  18172. + .phy_write = ar7240_dsa_phy_write,
  18173. + .poll_link = ar7240_dsa_poll_link,
  18174. + .get_strings = ar7240_dsa_get_strings,
  18175. + .get_ethtool_stats = ar7240_dsa_get_ethtool_stats,
  18176. + .get_sset_count = ar7240_dsa_get_sset_count,
  18177. +};
  18178. +
  18179. +int __init dsa_ar7240_init(void)
  18180. +{
  18181. + register_switch_driver(&ar7240_dsa_driver);
  18182. + return 0;
  18183. +}
  18184. +module_init(dsa_ar7240_init);
  18185. +
  18186. +void __exit dsa_ar7240_cleanup(void)
  18187. +{
  18188. + unregister_switch_driver(&ar7240_dsa_driver);
  18189. +}
  18190. +module_exit(dsa_ar7240_cleanup);
  18191. diff -Nur linux-2.6.37.orig/net/dsa/mv88e6063.c linux-2.6.37/net/dsa/mv88e6063.c
  18192. --- linux-2.6.37.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100
  18193. +++ linux-2.6.37/net/dsa/mv88e6063.c 2011-01-11 20:25:48.000000000 +0100
  18194. @@ -0,0 +1,294 @@
  18195. +/*
  18196. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips
  18197. + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  18198. + *
  18199. + * This driver was base on: net/dsa/mv88e6060.c
  18200. + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips
  18201. + * Copyright (c) 2008-2009 Marvell Semiconductor
  18202. + *
  18203. + * This program is free software; you can redistribute it and/or modify
  18204. + * it under the terms of the GNU General Public License as published by
  18205. + * the Free Software Foundation; either version 2 of the License, or
  18206. + * (at your option) any later version.
  18207. + */
  18208. +
  18209. +#include <linux/list.h>
  18210. +#include <linux/netdevice.h>
  18211. +#include <linux/phy.h>
  18212. +#include "dsa_priv.h"
  18213. +
  18214. +#define REG_BASE 0x10
  18215. +#define REG_PHY(p) (REG_BASE + (p))
  18216. +#define REG_PORT(p) (REG_BASE + 8 + (p))
  18217. +#define REG_GLOBAL (REG_BASE + 0x0f)
  18218. +#define NUM_PORTS 7
  18219. +
  18220. +static int reg_read(struct dsa_switch *ds, int addr, int reg)
  18221. +{
  18222. + return mdiobus_read(ds->master_mii_bus, addr, reg);
  18223. +}
  18224. +
  18225. +#define REG_READ(addr, reg) \
  18226. + ({ \
  18227. + int __ret; \
  18228. + \
  18229. + __ret = reg_read(ds, addr, reg); \
  18230. + if (__ret < 0) \
  18231. + return __ret; \
  18232. + __ret; \
  18233. + })
  18234. +
  18235. +
  18236. +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
  18237. +{
  18238. + return mdiobus_write(ds->master_mii_bus, addr, reg, val);
  18239. +}
  18240. +
  18241. +#define REG_WRITE(addr, reg, val) \
  18242. + ({ \
  18243. + int __ret; \
  18244. + \
  18245. + __ret = reg_write(ds, addr, reg, val); \
  18246. + if (__ret < 0) \
  18247. + return __ret; \
  18248. + })
  18249. +
  18250. +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr)
  18251. +{
  18252. + int ret;
  18253. +
  18254. + ret = mdiobus_read(bus, REG_PORT(0), 0x03);
  18255. + if (ret >= 0) {
  18256. + ret &= 0xfff0;
  18257. + if (ret == 0x1530)
  18258. + return "Marvell 88E6063";
  18259. + }
  18260. +
  18261. + return NULL;
  18262. +}
  18263. +
  18264. +static int mv88e6063_switch_reset(struct dsa_switch *ds)
  18265. +{
  18266. + int i;
  18267. + int ret;
  18268. +
  18269. + /*
  18270. + * Set all ports to the disabled state.
  18271. + */
  18272. + for (i = 0; i < NUM_PORTS; i++) {
  18273. + ret = REG_READ(REG_PORT(i), 0x04);
  18274. + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
  18275. + }
  18276. +
  18277. + /*
  18278. + * Wait for transmit queues to drain.
  18279. + */
  18280. + msleep(2);
  18281. +
  18282. + /*
  18283. + * Reset the switch.
  18284. + */
  18285. + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130);
  18286. +
  18287. + /*
  18288. + * Wait up to one second for reset to complete.
  18289. + */
  18290. + for (i = 0; i < 1000; i++) {
  18291. + ret = REG_READ(REG_GLOBAL, 0x00);
  18292. + if ((ret & 0x8000) == 0x0000)
  18293. + break;
  18294. +
  18295. + msleep(1);
  18296. + }
  18297. + if (i == 1000)
  18298. + return -ETIMEDOUT;
  18299. +
  18300. + return 0;
  18301. +}
  18302. +
  18303. +static int mv88e6063_setup_global(struct dsa_switch *ds)
  18304. +{
  18305. + /*
  18306. + * Disable discarding of frames with excessive collisions,
  18307. + * set the maximum frame size to 1536 bytes, and mask all
  18308. + * interrupt sources.
  18309. + */
  18310. + REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
  18311. +
  18312. + /*
  18313. + * Enable automatic address learning, set the address
  18314. + * database size to 1024 entries, and set the default aging
  18315. + * time to 5 minutes.
  18316. + */
  18317. + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
  18318. +
  18319. + return 0;
  18320. +}
  18321. +
  18322. +static int mv88e6063_setup_port(struct dsa_switch *ds, int p)
  18323. +{
  18324. + int addr = REG_PORT(p);
  18325. +
  18326. + /*
  18327. + * Do not force flow control, disable Ingress and Egress
  18328. + * Header tagging, disable VLAN tunneling, and set the port
  18329. + * state to Forwarding. Additionally, if this is the CPU
  18330. + * port, enable Ingress and Egress Trailer tagging mode.
  18331. + */
  18332. + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003);
  18333. +
  18334. + /*
  18335. + * Port based VLAN map: give each port its own address
  18336. + * database, allow the CPU port to talk to each of the 'real'
  18337. + * ports, and allow each of the 'real' ports to only talk to
  18338. + * the CPU port.
  18339. + */
  18340. + REG_WRITE(addr, 0x06,
  18341. + ((p & 0xf) << 12) |
  18342. + (dsa_is_cpu_port(ds, p) ?
  18343. + ds->phys_port_mask :
  18344. + (1 << ds->dst->cpu_port)));
  18345. +
  18346. + /*
  18347. + * Port Association Vector: when learning source addresses
  18348. + * of packets, add the address to the address database using
  18349. + * a port bitmap that has only the bit for this port set and
  18350. + * the other bits clear.
  18351. + */
  18352. + REG_WRITE(addr, 0x0b, 1 << p);
  18353. +
  18354. + return 0;
  18355. +}
  18356. +
  18357. +static int mv88e6063_setup(struct dsa_switch *ds)
  18358. +{
  18359. + int i;
  18360. + int ret;
  18361. +
  18362. + ret = mv88e6063_switch_reset(ds);
  18363. + if (ret < 0)
  18364. + return ret;
  18365. +
  18366. + /* @@@ initialise atu */
  18367. +
  18368. + ret = mv88e6063_setup_global(ds);
  18369. + if (ret < 0)
  18370. + return ret;
  18371. +
  18372. + for (i = 0; i < NUM_PORTS; i++) {
  18373. + ret = mv88e6063_setup_port(ds, i);
  18374. + if (ret < 0)
  18375. + return ret;
  18376. + }
  18377. +
  18378. + return 0;
  18379. +}
  18380. +
  18381. +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr)
  18382. +{
  18383. + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
  18384. + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
  18385. + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
  18386. +
  18387. + return 0;
  18388. +}
  18389. +
  18390. +static int mv88e6063_port_to_phy_addr(int port)
  18391. +{
  18392. + if (port >= 0 && port <= NUM_PORTS)
  18393. + return REG_PHY(port);
  18394. + return -1;
  18395. +}
  18396. +
  18397. +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum)
  18398. +{
  18399. + int addr;
  18400. +
  18401. + addr = mv88e6063_port_to_phy_addr(port);
  18402. + if (addr == -1)
  18403. + return 0xffff;
  18404. +
  18405. + return reg_read(ds, addr, regnum);
  18406. +}
  18407. +
  18408. +static int
  18409. +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
  18410. +{
  18411. + int addr;
  18412. +
  18413. + addr = mv88e6063_port_to_phy_addr(port);
  18414. + if (addr == -1)
  18415. + return 0xffff;
  18416. +
  18417. + return reg_write(ds, addr, regnum, val);
  18418. +}
  18419. +
  18420. +static void mv88e6063_poll_link(struct dsa_switch *ds)
  18421. +{
  18422. + int i;
  18423. +
  18424. + for (i = 0; i < DSA_MAX_PORTS; i++) {
  18425. + struct net_device *dev;
  18426. + int uninitialized_var(port_status);
  18427. + int link;
  18428. + int speed;
  18429. + int duplex;
  18430. + int fc;
  18431. +
  18432. + dev = ds->ports[i];
  18433. + if (dev == NULL)
  18434. + continue;
  18435. +
  18436. + link = 0;
  18437. + if (dev->flags & IFF_UP) {
  18438. + port_status = reg_read(ds, REG_PORT(i), 0x00);
  18439. + if (port_status < 0)
  18440. + continue;
  18441. +
  18442. + link = !!(port_status & 0x1000);
  18443. + }
  18444. +
  18445. + if (!link) {
  18446. + if (netif_carrier_ok(dev)) {
  18447. + printk(KERN_INFO "%s: link down\n", dev->name);
  18448. + netif_carrier_off(dev);
  18449. + }
  18450. + continue;
  18451. + }
  18452. +
  18453. + speed = (port_status & 0x0100) ? 100 : 10;
  18454. + duplex = (port_status & 0x0200) ? 1 : 0;
  18455. + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
  18456. +
  18457. + if (!netif_carrier_ok(dev)) {
  18458. + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
  18459. + "flow control %sabled\n", dev->name,
  18460. + speed, duplex ? "full" : "half",
  18461. + fc ? "en" : "dis");
  18462. + netif_carrier_on(dev);
  18463. + }
  18464. + }
  18465. +}
  18466. +
  18467. +static struct dsa_switch_driver mv88e6063_switch_driver = {
  18468. + .tag_protocol = htons(ETH_P_TRAILER),
  18469. + .probe = mv88e6063_probe,
  18470. + .setup = mv88e6063_setup,
  18471. + .set_addr = mv88e6063_set_addr,
  18472. + .phy_read = mv88e6063_phy_read,
  18473. + .phy_write = mv88e6063_phy_write,
  18474. + .poll_link = mv88e6063_poll_link,
  18475. +};
  18476. +
  18477. +static int __init mv88e6063_init(void)
  18478. +{
  18479. + register_switch_driver(&mv88e6063_switch_driver);
  18480. + return 0;
  18481. +}
  18482. +module_init(mv88e6063_init);
  18483. +
  18484. +static void __exit mv88e6063_cleanup(void)
  18485. +{
  18486. + unregister_switch_driver(&mv88e6063_switch_driver);
  18487. +}
  18488. +module_exit(mv88e6063_cleanup);
  18489. diff -Nur linux-2.6.37.orig/net/dsa/tag_qinq.c linux-2.6.37/net/dsa/tag_qinq.c
  18490. --- linux-2.6.37.orig/net/dsa/tag_qinq.c 1970-01-01 01:00:00.000000000 +0100
  18491. +++ linux-2.6.37/net/dsa/tag_qinq.c 2011-01-11 20:25:48.000000000 +0100
  18492. @@ -0,0 +1,127 @@
  18493. +/*
  18494. + * net/dsa/tag_qinq.c - QinQ tag format handling
  18495. + * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
  18496. + *
  18497. + * This file was based on:
  18498. + * net/dsa/tag_edsa.c - Ethertype DSA tagging
  18499. + * Copyright (c) 2008-2009 Marvell Semiconductor
  18500. + *
  18501. + * This program is free software; you can redistribute it and/or modify
  18502. + * it under the terms of the GNU General Public License as published by
  18503. + * the Free Software Foundation; either version 2 of the License, or
  18504. + * (at your option) any later version.
  18505. + */
  18506. +
  18507. +#include <linux/etherdevice.h>
  18508. +#include <linux/list.h>
  18509. +#include <linux/netdevice.h>
  18510. +#include <linux/if_vlan.h>
  18511. +
  18512. +#include "dsa_priv.h"
  18513. +
  18514. +netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev)
  18515. +{
  18516. + struct dsa_slave_priv *p = netdev_priv(dev);
  18517. + struct vlan_ethhdr *veth;
  18518. + unsigned int len;
  18519. + int ret;
  18520. +
  18521. + if (skb_cow_head(skb, VLAN_HLEN) < 0)
  18522. + goto out_free_skb;
  18523. +
  18524. + veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
  18525. +
  18526. + /* Move the mac addresses to the beginning of the new header. */
  18527. + memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
  18528. + skb->mac_header -= VLAN_HLEN;
  18529. +
  18530. + /* setup VLAN header fields */
  18531. + veth->h_vlan_proto = htons(ETH_P_QINQ);
  18532. + veth->h_vlan_TCI = htons(p->port);
  18533. +
  18534. + len = skb->len;
  18535. + skb->protocol = htons(ETH_P_QINQ);
  18536. + skb->dev = p->parent->dst->master_netdev;
  18537. +
  18538. + ret = dev_queue_xmit(skb);
  18539. + if (unlikely(ret != NET_XMIT_SUCCESS))
  18540. + goto out_dropped;
  18541. +
  18542. + dev->stats.tx_packets++;
  18543. + dev->stats.tx_bytes += len;
  18544. +
  18545. + return NETDEV_TX_OK;
  18546. +
  18547. + out_free_skb:
  18548. + kfree_skb(skb);
  18549. + out_dropped:
  18550. + dev->stats.tx_dropped++;
  18551. + return NETDEV_TX_OK;
  18552. +}
  18553. +
  18554. +static int qinq_rcv(struct sk_buff *skb, struct net_device *dev,
  18555. + struct packet_type *pt, struct net_device *orig_dev)
  18556. +{
  18557. + struct dsa_switch_tree *dst;
  18558. + struct dsa_switch *ds;
  18559. + struct vlan_hdr *vhdr;
  18560. + int source_port;
  18561. +
  18562. + dst = dev->dsa_ptr;
  18563. + if (unlikely(dst == NULL))
  18564. + goto out_drop;
  18565. + ds = dst->ds[0];
  18566. +
  18567. + skb = skb_unshare(skb, GFP_ATOMIC);
  18568. + if (skb == NULL)
  18569. + goto out;
  18570. +
  18571. + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
  18572. + goto out_drop;
  18573. +
  18574. + vhdr = (struct vlan_hdr *)skb->data;
  18575. + source_port = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
  18576. + if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
  18577. + goto out_drop;
  18578. +
  18579. + /* Remove the outermost VLAN tag and update checksum. */
  18580. + skb_pull_rcsum(skb, VLAN_HLEN);
  18581. + memmove(skb->data - ETH_HLEN,
  18582. + skb->data - ETH_HLEN - VLAN_HLEN,
  18583. + 2 * ETH_ALEN);
  18584. +
  18585. + skb->dev = ds->ports[source_port];
  18586. + skb_push(skb, ETH_HLEN);
  18587. + skb->pkt_type = PACKET_HOST;
  18588. + skb->protocol = eth_type_trans(skb, skb->dev);
  18589. +
  18590. + skb->dev->stats.rx_packets++;
  18591. + skb->dev->stats.rx_bytes += skb->len;
  18592. +
  18593. + netif_receive_skb(skb);
  18594. +
  18595. + return 0;
  18596. +
  18597. + out_drop:
  18598. + kfree_skb(skb);
  18599. + out:
  18600. + return 0;
  18601. +}
  18602. +
  18603. +static struct packet_type qinq_packet_type __read_mostly = {
  18604. + .type = cpu_to_be16(ETH_P_QINQ),
  18605. + .func = qinq_rcv,
  18606. +};
  18607. +
  18608. +static int __init qinq_init_module(void)
  18609. +{
  18610. + dev_add_pack(&qinq_packet_type);
  18611. + return 0;
  18612. +}
  18613. +module_init(qinq_init_module);
  18614. +
  18615. +static void __exit qinq_cleanup_module(void)
  18616. +{
  18617. + dev_remove_pack(&qinq_packet_type);
  18618. +}
  18619. +module_exit(qinq_cleanup_module);