| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332 | diff -Nur linux-2.6.37.orig/arch/mips/Kbuild.platforms linux-2.6.37/arch/mips/Kbuild.platforms--- linux-2.6.37.orig/arch/mips/Kbuild.platforms	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/Kbuild.platforms	2011-05-15 19:24:57.000000000 +0200@@ -5,6 +5,7 @@ platforms += bcm47xx platforms += bcm63xx platforms += cavium-octeon+platforms += ar231x platforms += cobalt platforms += dec platforms += emmadiff -Nur linux-2.6.37.orig/arch/mips/Kconfig linux-2.6.37/arch/mips/Kconfig--- linux-2.6.37.orig/arch/mips/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/Kconfig	2011-05-15 19:24:57.000000000 +0200@@ -102,6 +102,20 @@ 	help 	 Support for BCM63XX based boards +config ATHEROS_AR231X+	bool "Atheros 231x/531x SoC support"+	select CEVT_R4K+	select CSRC_R4K+	select DMA_NONCOHERENT+	select IRQ_CPU+	select SYS_HAS_CPU_MIPS32_R1+	select SYS_SUPPORTS_BIG_ENDIAN+	select SYS_SUPPORTS_32BIT_KERNEL+	select GENERIC_GPIO+	select SYS_HAS_EARLY_PRINTK+	help+	  Support for AR231x and AR531x based boards+ config MIPS_COBALT 	bool "Cobalt Server" 	select CEVT_R4K@@ -716,6 +730,7 @@  endchoice +source "arch/mips/ar231x/Kconfig" source "arch/mips/alchemy/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/jazz/Kconfig"diff -Nur linux-2.6.37.orig/arch/mips/ar231x/Kconfig linux-2.6.37/arch/mips/ar231x/Kconfig--- linux-2.6.37.orig/arch/mips/ar231x/Kconfig	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/Kconfig	2011-05-15 19:25:40.000000000 +0200@@ -0,0 +1,27 @@+config ATHEROS_AR5312+	bool "Atheros 5312/2312+ support"+	depends on ATHEROS_AR231X+	default y++config ATHEROS_AR2315+	bool "Atheros 2315+ support"+	depends on ATHEROS_AR231X+	select DMA_NONCOHERENT+	select CEVT_R4K+	select CSRC_R4K+	select IRQ_CPU+	select SYS_HAS_CPU_MIPS32_R1+	select SYS_SUPPORTS_32BIT_KERNEL+	select SYS_SUPPORTS_BIG_ENDIAN+	select GENERIC_GPIO+	default y++config ATHEROS_AR2315_PCI+	bool "PCI support"+	depends on ATHEROS_AR2315+	select HW_HAS_PCI+	select PCI+	select USB_ARCH_HAS_HCD+	select USB_ARCH_HAS_OHCI+	select USB_ARCH_HAS_EHCI+	default ndiff -Nur linux-2.6.37.orig/arch/mips/ar231x/Makefile linux-2.6.37/arch/mips/ar231x/Makefile--- linux-2.6.37.orig/arch/mips/ar231x/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/Makefile	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,17 @@+#+# This file is subject to the terms and conditions of the GNU General Public+# License.  See the file "COPYING" in the main directory of this archive+# for more details.+#+# Copyright (C) 2006 FON Technology, SL.+# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+# Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+#++obj-y += board.o prom.o devices.o++obj-$(CONFIG_EARLY_PRINTK) += early_printk.o++obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o+obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o+obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.odiff -Nur linux-2.6.37.orig/arch/mips/ar231x/Platform linux-2.6.37/arch/mips/ar231x/Platform--- linux-2.6.37.orig/arch/mips/ar231x/Platform	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/Platform	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,6 @@+#+# Atheros AR5312/AR2312 WiSoC+#+platform-$(CONFIG_ATHEROS_AR231X)          += ar231x/+cflags-$(CONFIG_ATHEROS_AR231X)        += -I$(srctree)/arch/mips/include/asm/mach-ar231x+load-$(CONFIG_ATHEROS_AR231X)          += 0xffffffff80041000diff -Nur linux-2.6.37.orig/arch/mips/ar231x/ar2315.c linux-2.6.37/arch/mips/ar231x/ar2315.c--- linux-2.6.37.orig/arch/mips/ar231x/ar2315.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/ar2315.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,683 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>+ */++/*+ * Platform devices for Atheros SoCs+ */++#include <generated/autoconf.h>+#include <linux/init.h>+#include <linux/module.h>+#include <linux/types.h>+#include <linux/string.h>+#include <linux/platform_device.h>+#include <linux/kernel.h>+#include <linux/reboot.h>+#include <linux/delay.h>+#include <linux/leds.h>+#include <asm/bootinfo.h>+#include <asm/reboot.h>+#include <asm/time.h>+#include <asm/irq.h>+#include <asm/io.h>+#include <asm/gpio.h>++#include <ar231x_platform.h>+#include <ar2315_regs.h>+#include <ar231x.h>+#include "devices.h"+#include "ar2315.h"++static u32 gpiointmask = 0, gpiointval = 0;++static inline void ar2315_gpio_irq(void)+{+	u32 pend;+	int bit = -1;++	/* only do one gpio interrupt at a time */+	pend = (ar231x_read_reg(AR2315_GPIO_DI) ^ gpiointval) & gpiointmask;++	if (pend) {+		bit = fls(pend) - 1;+		pend &= ~(1 << bit);+		gpiointval ^= (1 << bit);+	}++	if (!pend)+		ar231x_write_reg(AR2315_ISR, AR2315_ISR_GPIO);++	/* Enable interrupt with edge detection */+	if ((ar231x_read_reg(AR2315_GPIO_CR) & AR2315_GPIO_CR_M(bit)) != AR2315_GPIO_CR_I(bit))+		return;++	if (bit >= 0)+		do_IRQ(AR531X_GPIO_IRQ_BASE + bit);+}++#ifdef CONFIG_ATHEROS_AR2315_PCI+static inline void pci_abort_irq(void)+{+	ar231x_write_reg(AR2315_PCI_INT_STATUS, AR2315_PCI_ABORT_INT);+}++static inline void pci_ack_irq(void)+{+	ar231x_write_reg(AR2315_PCI_INT_STATUS, AR2315_PCI_EXT_INT);+}++void ar2315_pci_irq(int irq)+{+	if (ar231x_read_reg(AR2315_PCI_INT_STATUS) == AR2315_PCI_ABORT_INT)+		pci_abort_irq();+	else {+		do_IRQ(irq);+		pci_ack_irq();+	}+}+#endif /* CONFIG_ATHEROS_AR2315_PCI */++/*+ * Called when an interrupt is received, this function+ * determines exactly which interrupt it was, and it+ * invokes the appropriate handler.+ *+ * Implicitly, we also define interrupt priority by+ * choosing which to dispatch first.+ */+static asmlinkage void+ar2315_irq_dispatch(void)+{+	int pending = read_c0_status() & read_c0_cause();++	if (pending & CAUSEF_IP3)+		do_IRQ(AR2315_IRQ_WLAN0_INTRS);+	else if (pending & CAUSEF_IP4)+		do_IRQ(AR2315_IRQ_ENET0_INTRS);+#ifdef CONFIG_ATHEROS_AR2315_PCI+	else if (pending & CAUSEF_IP5)+		ar2315_pci_irq(AR2315_IRQ_LCBUS_PCI);+#endif+	else if (pending & CAUSEF_IP2) {+		unsigned int misc_intr = ar231x_read_reg(AR2315_ISR) & ar231x_read_reg(AR2315_IMR);++		if (misc_intr & AR2315_ISR_SPI)+			do_IRQ(AR531X_MISC_IRQ_SPI);+		else if (misc_intr & AR2315_ISR_TIMER)+			do_IRQ(AR531X_MISC_IRQ_TIMER);+		else if (misc_intr & AR2315_ISR_AHB)+			do_IRQ(AR531X_MISC_IRQ_AHB_PROC);+		else if (misc_intr & AR2315_ISR_GPIO)+			ar2315_gpio_irq();+		else if (misc_intr & AR2315_ISR_UART0)+			do_IRQ(AR531X_MISC_IRQ_UART0);+		else if (misc_intr & AR2315_ISR_WD)+			do_IRQ(AR531X_MISC_IRQ_WATCHDOG);+		else+			do_IRQ(AR531X_MISC_IRQ_NONE);+	} else if (pending & CAUSEF_IP7)+		do_IRQ(AR531X_IRQ_CPU_CLOCK);+}++static void ar2315_set_gpiointmask(int gpio, int level)+{+	u32 reg;++	reg = ar231x_read_reg(AR2315_GPIO_INT);+	reg &= ~(AR2315_GPIO_INT_M | AR2315_GPIO_INT_LVL_M);+	reg |= gpio | AR2315_GPIO_INT_LVL(level);+	ar231x_write_reg(AR2315_GPIO_INT, reg);+}++static void ar2315_gpio_intr_enable(unsigned int irq)+{+	unsigned int gpio = irq - AR531X_GPIO_IRQ_BASE;++	/* Enable interrupt with edge detection */+	if ((ar231x_read_reg(AR2315_GPIO_CR) & AR2315_GPIO_CR_M(gpio)) != AR2315_GPIO_CR_I(gpio))+		return;++	gpiointmask |= (1 << gpio);+	ar2315_set_gpiointmask(gpio, 3);+}++static unsigned int ar2315_gpio_intr_startup(unsigned int irq)+{+	unsigned int gpio = irq - AR531X_GPIO_IRQ_BASE;++	/* reconfigure GPIO line as input */+	ar231x_mask_reg(AR2315_GPIO_CR, AR2315_GPIO_CR_M(gpio), AR2315_GPIO_CR_I(gpio));+	ar2315_gpio_intr_enable(irq);+	return 0;+}++static void ar2315_gpio_intr_disable(unsigned int irq)+{+	unsigned int gpio = irq - AR531X_GPIO_IRQ_BASE;++	/* Disable interrupt */+	gpiointmask &= ~(1 << gpio);+	ar2315_set_gpiointmask(gpio, 0);+}++static void+ar2315_gpio_intr_end(unsigned int irq)+{+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))+		ar2315_gpio_intr_enable(irq);+}++static struct irq_chip ar2315_gpio_intr_controller = {+	.name	= "AR2315-GPIO",+	.startup  = ar2315_gpio_intr_startup,+	.ack      = ar2315_gpio_intr_disable,+	.mask_ack = ar2315_gpio_intr_disable,+	.mask     = ar2315_gpio_intr_disable,+	.unmask   = ar2315_gpio_intr_enable,+	.end      = ar2315_gpio_intr_end,+};++static void+ar2315_misc_intr_enable(unsigned int irq)+{+	unsigned int imr;++	imr = ar231x_read_reg(AR2315_IMR);+	switch(irq) {+	case AR531X_MISC_IRQ_SPI:+		 imr |= AR2315_ISR_SPI;+		 break;+	case AR531X_MISC_IRQ_TIMER:+	     imr |= AR2315_ISR_TIMER;+	     break;+	case AR531X_MISC_IRQ_AHB_PROC:+	     imr |= AR2315_ISR_AHB;+	     break;+	case AR531X_MISC_IRQ_GPIO:+	     imr |= AR2315_ISR_GPIO;+	     break;+	case AR531X_MISC_IRQ_UART0:+	     imr |= AR2315_ISR_UART0;+	     break;+	case AR531X_MISC_IRQ_WATCHDOG:+	     imr |= AR2315_ISR_WD;+	     break;+	default:+		break;+	}+	ar231x_write_reg(AR2315_IMR, imr);+}++static void+ar2315_misc_intr_disable(unsigned int irq)+{+	unsigned int imr;++	imr = ar231x_read_reg(AR2315_IMR);+	switch(irq) {+	case AR531X_MISC_IRQ_SPI:+		 imr &= ~AR2315_ISR_SPI;+		 break;+	case AR531X_MISC_IRQ_TIMER:+	     imr &= ~AR2315_ISR_TIMER;+	     break;+	case AR531X_MISC_IRQ_AHB_PROC:+	     imr &= ~AR2315_ISR_AHB;+	     break;+	case AR531X_MISC_IRQ_GPIO:+	     imr &= ~AR2315_ISR_GPIO;+	     break;+	case AR531X_MISC_IRQ_UART0:+	     imr &= ~AR2315_ISR_UART0;+	     break;+	case AR531X_MISC_IRQ_WATCHDOG:+	     imr &= ~AR2315_ISR_WD;+	     break;+	default:+		break;+	}+	ar231x_write_reg(AR2315_IMR, imr);+}++static void+ar2315_misc_intr_end(unsigned int irq)+{+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))+		ar2315_misc_intr_enable(irq);+}+++static struct irq_chip ar2315_misc_intr_controller = {+	.name	= "AR2315-MISC",+	.ack      = ar2315_misc_intr_disable,+	.mask_ack = ar2315_misc_intr_disable,+	.mask     = ar2315_misc_intr_disable,+	.unmask   = ar2315_misc_intr_enable,+	.end      = ar2315_misc_intr_end,+};++static irqreturn_t ar2315_ahb_proc_handler(int cpl, void *dev_id)+{+    ar231x_write_reg(AR2315_AHB_ERR0, AHB_ERROR_DET);+    ar231x_read_reg(AR2315_AHB_ERR1);++    printk(KERN_ERR "AHB fatal error\n");+    machine_restart("AHB error"); /* Catastrophic failure */++    return IRQ_HANDLED;+}++static struct irqaction ar2315_ahb_proc_interrupt  = {+	.handler	= ar2315_ahb_proc_handler,+	.flags		= IRQF_DISABLED,+	.name		= "ar2315_ahb_proc_interrupt",+};++static struct irqaction cascade  = {+	.handler	= no_action,+	.flags		= IRQF_DISABLED,+	.name		= "cascade",+};++void+ar2315_irq_init(void)+{+	int i;++	if (!is_2315())+		return;++	ar231x_irq_dispatch = ar2315_irq_dispatch;+	gpiointval = ar231x_read_reg(AR2315_GPIO_DI);+	for (i = 0; i < AR531X_MISC_IRQ_COUNT; i++) {+		int irq = AR531X_MISC_IRQ_BASE + i;+		set_irq_chip_and_handler(irq, &ar2315_misc_intr_controller,+			handle_level_irq);+	}+	for (i = 0; i < AR531X_GPIO_IRQ_COUNT; i++) {+		int irq = AR531X_GPIO_IRQ_BASE + i;+		set_irq_chip_and_handler(irq, &ar2315_gpio_intr_controller,+			handle_level_irq);+	}+	setup_irq(AR531X_MISC_IRQ_GPIO, &cascade);+	setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar2315_ahb_proc_interrupt);+	setup_irq(AR2315_IRQ_MISC_INTRS, &cascade);+}++const struct ar231x_gpiodev ar2315_gpiodev;++static u32+ar2315_gpio_get_output(void)+{+	u32 reg;+	reg = ar231x_read_reg(AR2315_GPIO_CR);+	reg &= ar2315_gpiodev.valid_mask;+	return reg;+}++static u32+ar2315_gpio_set_output(u32 mask, u32 val)+{+	u32 reg;++	reg = ar231x_read_reg(AR2315_GPIO_CR);+	reg &= ~mask;+	reg |= val;+	ar231x_write_reg(AR2315_GPIO_CR, reg);+	return reg;+}++static u32+ar2315_gpio_get(void)+{+	u32 reg;+	reg = ar231x_read_reg(AR2315_GPIO_DI);+	reg &= ar2315_gpiodev.valid_mask;+	return reg;+}++static u32+ar2315_gpio_set(u32 mask, u32 value)+{+	u32 reg;+	reg = ar231x_read_reg(AR2315_GPIO_DO);+	reg &= ~mask;+	reg |= value;+	ar231x_write_reg(AR2315_GPIO_DO, reg);+	return reg;+}++const struct ar231x_gpiodev ar2315_gpiodev = {+	.valid_mask = (1 << 22) - 1,+	.get_output = ar2315_gpio_get_output,+	.set_output = ar2315_gpio_set_output,+	.get = ar2315_gpio_get,+	.set = ar2315_gpio_set,+};++static struct ar231x_eth ar2315_eth_data = {+	.reset_base = AR2315_RESET,+	.reset_mac = AR2315_RESET_ENET0,+	.reset_phy = AR2315_RESET_EPHY0,+	.phy_base = AR2315_ENET0,+	.config = &ar231x_board,+};++static struct resource ar2315_spiflash_res[] = {+	{+		.name = "flash_base",+		.flags = IORESOURCE_MEM,+		.start = KSEG1ADDR(AR2315_SPI_READ),+		.end = KSEG1ADDR(AR2315_SPI_READ) + 0x1000000 - 1,+	},+	{+		.name = "flash_regs",+		.flags = IORESOURCE_MEM,+		.start = 0x11300000,+		.end = 0x11300012,+	},+};++static struct platform_device ar2315_spiflash = {+	.id = 0,+	.name = "spiflash",+	.resource = ar2315_spiflash_res,+	.num_resources = ARRAY_SIZE(ar2315_spiflash_res)+};++static struct platform_device ar2315_wdt = {+	.id = 0,+	.name = "ar2315_wdt",+};++#define SPI_FLASH_CTL      0x00+#define SPI_FLASH_OPCODE   0x04+#define SPI_FLASH_DATA     0x08++static inline u32+spiflash_read_reg(int reg)+{+	return ar231x_read_reg(KSEG1ADDR(AR2315_SPI) + reg);+}++static inline void+spiflash_write_reg(int reg, u32 data)+{+	ar231x_write_reg(KSEG1ADDR(AR2315_SPI) + reg, data);+}++static u32+spiflash_wait_status(void)+{+	u32 reg;++	do {+		reg = spiflash_read_reg(SPI_FLASH_CTL);+	} while (reg & SPI_CTL_BUSY);++	return reg;+}++static u8+spiflash_probe(void)+{+	u32 reg;++	reg = spiflash_wait_status();+	reg &= ~SPI_CTL_TX_RX_CNT_MASK;+	reg |= (1 << 4) | 4 | SPI_CTL_START;++	spiflash_write_reg(SPI_FLASH_OPCODE, 0xab);+	spiflash_write_reg(SPI_FLASH_CTL, reg);++	reg = spiflash_wait_status();+	reg = spiflash_read_reg(SPI_FLASH_DATA);+	reg &= 0xff;++	return (u8) reg;+}+++#define STM_8MBIT_SIGNATURE     0x13+#define STM_16MBIT_SIGNATURE    0x14+#define STM_32MBIT_SIGNATURE    0x15+#define STM_64MBIT_SIGNATURE    0x16+#define STM_128MBIT_SIGNATURE   0x17++static u8 __init *+ar2315_flash_limit(void)+{+	u32 flash_size = 0;++	/* probe the flash chip size */+	switch(spiflash_probe()) {+		case STM_8MBIT_SIGNATURE:+			flash_size = 0x00100000;+			break;+		case STM_16MBIT_SIGNATURE:+			flash_size = 0x00200000;+			break;+		case STM_32MBIT_SIGNATURE:+			flash_size = 0x00400000;+			break;+		case STM_64MBIT_SIGNATURE:+			flash_size = 0x00800000;+			break;+		case STM_128MBIT_SIGNATURE:+			flash_size = 0x01000000;+			break;+	}++	ar2315_spiflash_res[0].end = ar2315_spiflash_res[0].start ++		flash_size - 1;+	return (u8 *) ar2315_spiflash_res[0].end + 1;+}++#ifdef CONFIG_LEDS_GPIO+static struct gpio_led ar2315_leds[6];+static struct gpio_led_platform_data ar2315_led_data = {+	.leds = (void *) ar2315_leds,+};++static struct platform_device ar2315_gpio_leds = {+	.name = "leds-gpio",+	.id = -1,+	.dev = {+		.platform_data = (void *) &ar2315_led_data,+	}+};++static void __init+ar2315_init_gpio(void)+{+	static char led_names[6][6];+	int i, led = 0;++	ar2315_led_data.num_leds = 0;+	for(i = 1; i < 8; i++)+	{+		if((i == AR2315_RESET_GPIO) ||+		   (i == ar231x_board.config->resetConfigGpio))+			continue;++		if(i == ar231x_board.config->sysLedGpio)+			strcpy(led_names[led], "wlan");+		else+			sprintf(led_names[led], "gpio%d", i);++		ar2315_leds[led].name = led_names[led];+		ar2315_leds[led].gpio = i;+		ar2315_leds[led].active_low = 0;+		led++;+	}+	ar2315_led_data.num_leds = led;+	platform_device_register(&ar2315_gpio_leds);+}+#else+static inline void ar2315_init_gpio(void)+{+}+#endif++int __init+ar2315_init_devices(void)+{+	if (!is_2315())+		return 0;++	/* Find board configuration */+	ar231x_find_config(ar2315_flash_limit());+	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;++	ar2315_init_gpio();+	platform_device_register(&ar2315_wdt);+	platform_device_register(&ar2315_spiflash);+	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,+		&ar2315_eth_data);+	ar231x_add_wmac(0, AR2315_WLAN0, AR2315_IRQ_WLAN0_INTRS);++	return 0;+}++static void+ar2315_restart(char *command)+{+	void (*mips_reset_vec)(void) = (void *) 0xbfc00000;++	local_irq_disable();++	/* try reset the system via reset control */+	ar231x_write_reg(AR2315_COLD_RESET,AR2317_RESET_SYSTEM);++	/* Cold reset does not work on the AR2315/6, use the GPIO reset bits a workaround.+	 * give it some time to attempt a gpio based hardware reset+	 * (atheros reference design workaround) */+	gpio_direction_output(AR2315_RESET_GPIO, 0);+	mdelay(100);++	/* Some boards (e.g. Senao EOC-2610) don't implement the reset logic+	 * workaround. Attempt to jump to the mips reset location -+	 * the boot loader itself might be able to recover the system */+	mips_reset_vec();+}+++/*+ * This table is indexed by bits 5..4 of the CLOCKCTL1 register+ * to determine the predevisor value.+ */+static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = { 1, 2, 4, 5 };+static int __initdata PLLC_DIVIDE_TABLE[5] = { 2, 3, 4, 6, 3 };++static unsigned int __init+ar2315_sys_clk(unsigned int clockCtl)+{+    unsigned int pllcCtrl,cpuDiv;+    unsigned int pllcOut,refdiv,fdiv,divby2;+	unsigned int clkDiv;++    pllcCtrl = ar231x_read_reg(AR2315_PLLC_CTL);+    refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S;+    refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv];+    fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S;+    divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S;+    divby2 += 1;+    pllcOut = (40000000/refdiv)*(2*divby2)*fdiv;+++    /* clkm input selected */+	switch(clockCtl & CPUCLK_CLK_SEL_M) {+		case 0:+		case 1:+			clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S];+			break;+		case 2:+			clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S];+			break;+		default:+			pllcOut = 40000000;+			clkDiv = 1;+			break;+	}+	cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;+	cpuDiv = cpuDiv * 2 ?: 1;+	return (pllcOut/(clkDiv * cpuDiv));+}++static inline unsigned int+ar2315_cpu_frequency(void)+{+    return ar2315_sys_clk(ar231x_read_reg(AR2315_CPUCLK));+}++static inline unsigned int+ar2315_apb_frequency(void)+{+    return ar2315_sys_clk(ar231x_read_reg(AR2315_AMBACLK));+}++void __init+ar2315_time_init(void)+{+	if (!is_2315())+		return;++	mips_hpt_frequency = ar2315_cpu_frequency() / 2;+}++void __init+ar2315_prom_init(void)+{+	u32 memsize, memcfg, devid;++	if (!is_2315())+		return;++	memcfg = ar231x_read_reg(AR2315_MEM_CFG);+	memsize   = 1 + ((memcfg & SDRAM_DATA_WIDTH_M) >> SDRAM_DATA_WIDTH_S);+	memsize <<= 1 + ((memcfg & SDRAM_COL_WIDTH_M) >> SDRAM_COL_WIDTH_S);+	memsize <<= 1 + ((memcfg & SDRAM_ROW_WIDTH_M) >> SDRAM_ROW_WIDTH_S);+	memsize <<= 3;+	add_memory_region(0, memsize, BOOT_MEM_RAM);++	/* Detect the hardware based on the device ID */+	devid = ar231x_read_reg(AR2315_SREV) & AR2315_REV_CHIP;+	switch(devid) {+		case 0x90:+		case 0x91:+			ar231x_devtype = DEV_TYPE_AR2317;+			break;+		default:+			ar231x_devtype = DEV_TYPE_AR2315;+			break;+	}+	ar231x_gpiodev = &ar2315_gpiodev;+	ar231x_board.devid = devid;+}++void __init+ar2315_plat_setup(void)+{+	u32 config;++	if (!is_2315())+		return;++	/* Clear any lingering AHB errors */+	config = read_c0_config();+	write_c0_config(config & ~0x3);+	ar231x_write_reg(AR2315_AHB_ERR0,AHB_ERROR_DET);+	ar231x_read_reg(AR2315_AHB_ERR1);+	ar231x_write_reg(AR2315_WDC, AR2315_WDC_IGNORE_EXPIRATION);++	_machine_restart = ar2315_restart;+	ar231x_serial_setup(KSEG1ADDR(AR2315_UART0), ar2315_apb_frequency());+}diff -Nur linux-2.6.37.orig/arch/mips/ar231x/ar2315.h linux-2.6.37/arch/mips/ar231x/ar2315.h--- linux-2.6.37.orig/arch/mips/ar231x/ar2315.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/ar2315.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,37 @@+#ifndef __AR2315_H+#define __AR2315_H++#ifdef CONFIG_ATHEROS_AR2315++extern void ar2315_irq_init(void);+extern int ar2315_init_devices(void);+extern void ar2315_prom_init(void);+extern void ar2315_plat_setup(void);+extern void ar2315_time_init(void);++#else++static inline void ar2315_irq_init(void)+{+}++static inline int ar2315_init_devices(void)+{+	return 0;+}++static inline void ar2315_prom_init(void)+{+}++static inline void ar2315_plat_setup(void)+{+}++static inline void ar2315_time_init(void)+{+}++#endif++#endifdiff -Nur linux-2.6.37.orig/arch/mips/ar231x/ar5312.c linux-2.6.37/arch/mips/ar231x/ar5312.c--- linux-2.6.37.orig/arch/mips/ar231x/ar5312.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/ar5312.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,549 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ */++/*+ * Platform devices for Atheros SoCs+ */++#include <generated/autoconf.h>+#include <linux/init.h>+#include <linux/module.h>+#include <linux/types.h>+#include <linux/string.h>+#include <linux/mtd/physmap.h>+#include <linux/platform_device.h>+#include <linux/kernel.h>+#include <linux/reboot.h>+#include <linux/leds.h>+#include <asm/bootinfo.h>+#include <asm/reboot.h>+#include <asm/time.h>+#include <asm/irq.h>+#include <asm/io.h>+#include <gpio.h>++#include <ar231x_platform.h>+#include <ar5312_regs.h>+#include <ar231x.h>+#include "devices.h"+#include "ar5312.h"++static void+ar5312_misc_irq_dispatch(void)+{+	unsigned int ar231x_misc_intrs = ar231x_read_reg(AR531X_ISR) & ar231x_read_reg(AR531X_IMR);++	if (ar231x_misc_intrs & AR531X_ISR_TIMER) {+		do_IRQ(AR531X_MISC_IRQ_TIMER);+		(void)ar231x_read_reg(AR531X_TIMER);+	} else if (ar231x_misc_intrs & AR531X_ISR_AHBPROC)+		do_IRQ(AR531X_MISC_IRQ_AHB_PROC);+	else if ((ar231x_misc_intrs & AR531X_ISR_UART0))+		do_IRQ(AR531X_MISC_IRQ_UART0);+	else if (ar231x_misc_intrs & AR531X_ISR_WD)+		do_IRQ(AR531X_MISC_IRQ_WATCHDOG);+	else+		do_IRQ(AR531X_MISC_IRQ_NONE);+}++static asmlinkage void+ar5312_irq_dispatch(void)+{+	int pending = read_c0_status() & read_c0_cause();++	if (pending & CAUSEF_IP2)+		do_IRQ(AR5312_IRQ_WLAN0_INTRS);+	else if (pending & CAUSEF_IP3)+		do_IRQ(AR5312_IRQ_ENET0_INTRS);+	else if (pending & CAUSEF_IP4)+		do_IRQ(AR5312_IRQ_ENET1_INTRS);+	else if (pending & CAUSEF_IP5)+		do_IRQ(AR5312_IRQ_WLAN1_INTRS);+	else if (pending & CAUSEF_IP6)+		ar5312_misc_irq_dispatch();+	else if (pending & CAUSEF_IP7)+		do_IRQ(AR531X_IRQ_CPU_CLOCK);+}+++/* Enable the specified AR531X_MISC_IRQ interrupt */+static void+ar5312_misc_intr_enable(unsigned int irq)+{+	unsigned int imr;++	imr = ar231x_read_reg(AR531X_IMR);+	imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1));+	ar231x_write_reg(AR531X_IMR, imr);+}++/* Disable the specified AR531X_MISC_IRQ interrupt */+static void+ar5312_misc_intr_disable(unsigned int irq)+{+	unsigned int imr;++	imr = ar231x_read_reg(AR531X_IMR);+	imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1));+	ar231x_write_reg(AR531X_IMR, imr);+	ar231x_read_reg(AR531X_IMR); /* flush write buffer */+}++static void+ar5312_misc_intr_end(unsigned int irq)+{+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))+		ar5312_misc_intr_enable(irq);+}++static struct irq_chip ar5312_misc_intr_controller = {+	.name     = "AR5312-MISC",+	.disable  = ar5312_misc_intr_disable,+	.ack      = ar5312_misc_intr_disable,+	.mask_ack = ar5312_misc_intr_disable,+	.mask     = ar5312_misc_intr_disable,+	.unmask   = ar5312_misc_intr_enable,+	.end      = ar5312_misc_intr_end,+};+++static irqreturn_t ar5312_ahb_proc_handler(int cpl, void *dev_id)+{+	u32 proc1 = ar231x_read_reg(AR531X_PROC1);+	u32 procAddr = ar231x_read_reg(AR531X_PROCADDR); /* clears error state */+	u32 dma1 = ar231x_read_reg(AR531X_DMA1);+	u32 dmaAddr = ar231x_read_reg(AR531X_DMAADDR);   /* clears error state */++	printk("AHB interrupt: PROCADDR=0x%8.8x  PROC1=0x%8.8x  DMAADDR=0x%8.8x  DMA1=0x%8.8x\n",+			procAddr, proc1, dmaAddr, dma1);++	machine_restart("AHB error"); /* Catastrophic failure */+	return IRQ_HANDLED;+}+++static struct irqaction ar5312_ahb_proc_interrupt  = {+	.handler = ar5312_ahb_proc_handler,+	.flags   = IRQF_DISABLED,+	.name    = "ar5312_ahb_proc_interrupt",+};+++static struct irqaction cascade  = {+	.handler = no_action,+	.flags   = IRQF_DISABLED,+	.name    = "cascade",+};++void __init ar5312_irq_init(void)+{+	int i;++	if (!is_5312())+		return;++	ar231x_irq_dispatch = ar5312_irq_dispatch;+	for (i = 0; i < AR531X_MISC_IRQ_COUNT; i++) {+		int irq = AR531X_MISC_IRQ_BASE + i;+		set_irq_chip_and_handler(irq, &ar5312_misc_intr_controller,+			handle_level_irq);+	}+	setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar5312_ahb_proc_interrupt);+	setup_irq(AR5312_IRQ_MISC_INTRS, &cascade);+}++const struct ar231x_gpiodev ar5312_gpiodev;++static u32+ar5312_gpio_get_output(void)+{+	u32 reg;+	reg = ~(ar231x_read_reg(AR531X_GPIO_CR));+	reg &= ar5312_gpiodev.valid_mask;+	return reg;+}++static u32+ar5312_gpio_set_output(u32 mask, u32 val)+{+	u32 reg;++	reg = ar231x_read_reg(AR531X_GPIO_CR);+	reg |= mask;+	reg &= ~val;+	ar231x_write_reg(AR531X_GPIO_CR, reg);+	return reg;+}++static u32+ar5312_gpio_get(void)+{+	u32 reg;+	reg = ar231x_read_reg(AR531X_GPIO_DI);+	reg &= ar5312_gpiodev.valid_mask;+	return reg;+}++static u32+ar5312_gpio_set(u32 mask, u32 value)+{+	u32 reg;+	reg = ar231x_read_reg(AR531X_GPIO_DO);+	reg &= ~mask;+	reg |= value;+	ar231x_write_reg(AR531X_GPIO_DO, reg);+	return reg;+}++const struct ar231x_gpiodev ar5312_gpiodev = {+	.valid_mask = (1 << 8) - 1,+	.get_output = ar5312_gpio_get_output,+	.set_output = ar5312_gpio_set_output,+	.get = ar5312_gpio_get,+	.set = ar5312_gpio_set,+};++static struct physmap_flash_data ar5312_flash_data = {+	.width = 2,+};++static struct resource ar5312_flash_resource = {+	.start = AR531X_FLASH,+	.end = AR531X_FLASH + 0x800000 - 1,+	.flags = IORESOURCE_MEM,+};++static struct ar231x_eth ar5312_eth0_data = {+	.reset_base = AR531X_RESET,+	.reset_mac = AR531X_RESET_ENET0,+	.reset_phy = AR531X_RESET_EPHY0,+	.phy_base = KSEG1ADDR(AR531X_ENET0),+	.config = &ar231x_board,+};++static struct ar231x_eth ar5312_eth1_data = {+	.reset_base = AR531X_RESET,+	.reset_mac = AR531X_RESET_ENET1,+	.reset_phy = AR531X_RESET_EPHY1,+	.phy_base = KSEG1ADDR(AR531X_ENET1),+	.config = &ar231x_board,+};++static struct platform_device ar5312_physmap_flash = {+	.name = "physmap-flash",+	.id = 0,+	.dev.platform_data = &ar5312_flash_data,+	.resource = &ar5312_flash_resource,+	.num_resources = 1,+};++#ifdef CONFIG_LEDS_GPIO+static struct gpio_led ar5312_leds[] = {+	{ .name = "wlan", .gpio = 0, .active_low = 1, },+};++static const struct gpio_led_platform_data ar5312_led_data = {+	.num_leds = ARRAY_SIZE(ar5312_leds),+	.leds = (void *) ar5312_leds,+};++static struct platform_device ar5312_gpio_leds = {+	.name = "leds-gpio",+	.id = -1,+	.dev.platform_data = (void *) &ar5312_led_data,+};+#endif++/*+ * NB: This mapping size is larger than the actual flash size,+ * but this shouldn't be a problem here, because the flash+ * will simply be mapped multiple times.+ */+static char __init *ar5312_flash_limit(void)+{+	u32 ctl;+	/*+	 * Configure flash bank 0.+	 * Assume 8M window size. Flash will be aliased if it's smaller+	 */+	ctl = FLASHCTL_E |+		FLASHCTL_AC_8M |+		FLASHCTL_RBLE |+		(0x01 << FLASHCTL_IDCY_S) |+		(0x07 << FLASHCTL_WST1_S) |+		(0x07 << FLASHCTL_WST2_S) |+		(ar231x_read_reg(AR531X_FLASHCTL0) & FLASHCTL_MW);++	ar231x_write_reg(AR531X_FLASHCTL0, ctl);++	/* Disable other flash banks */+	ar231x_write_reg(AR531X_FLASHCTL1,+		ar231x_read_reg(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC));++	ar231x_write_reg(AR531X_FLASHCTL2,+		ar231x_read_reg(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC));++	return (char *) KSEG1ADDR(AR531X_FLASH + 0x800000);+}++int __init ar5312_init_devices(void)+{+	struct ar231x_boarddata *config;+	u32 fctl = 0;+	const u8 *radio;+	u8 *c;++	if (!is_5312())+		return 0;++	/* Locate board/radio config data */+	ar231x_find_config(ar5312_flash_limit());+	config = ar231x_board.config;+++	/*+	 * Chip IDs and hardware detection for some Atheros+	 * models are really broken!+	 *+	 * Atheros uses a disabled WMAC0 and Silicon ID of AR5312+	 * as indication for AR2312, which is otherwise+	 * indistinguishable from the real AR5312.+	 */+	if (ar231x_board.radio) {+		radio = ar231x_board.radio + AR531X_RADIO_MASK_OFF;+		if ((*((const u32 *) radio) & AR531X_RADIO0_MASK) == 0)+			config->flags |= BD_ISCASPER;+	} else+		radio = NULL;++	/* AR2313 has CPU minor rev. 10 */+	if ((current_cpu_data.processor_id & 0xff) == 0x0a)+		ar231x_devtype = DEV_TYPE_AR2313;++	/* AR2312 shares the same Silicon ID as AR5312 */+	else if (config->flags & BD_ISCASPER)+		ar231x_devtype = DEV_TYPE_AR2312;++	/* Everything else is probably AR5312 or compatible */+	else+		ar231x_devtype = DEV_TYPE_AR5312;++	/* fixup flash width */+	fctl = ar231x_read_reg(AR531X_FLASHCTL) & FLASHCTL_MW;+	switch (fctl) {+	case FLASHCTL_MWx16:+		ar5312_flash_data.width = 2;+		break;+	case FLASHCTL_MWx8:+	default:+		ar5312_flash_data.width = 1;+		break;+	}++	platform_device_register(&ar5312_physmap_flash);++#ifdef CONFIG_LEDS_GPIO+	ar5312_leds[0].gpio = config->sysLedGpio;+	platform_device_register(&ar5312_gpio_leds);+#endif++	/* Fix up MAC addresses if necessary */+	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))+		memcpy(config->enet0_mac, config->enet1_mac, 6);++	/* If ENET0 and ENET1 have the same mac address,+	 * increment the one from ENET1 */+	if (memcmp(config->enet0_mac, config->enet1_mac, 6) == 0) {+		c = config->enet1_mac + 5;+		while ((c >= config->enet1_mac) && !(++(*c)))+			c--;+	}++	switch(ar231x_devtype) {+	case DEV_TYPE_AR5312:+		ar5312_eth0_data.macaddr = config->enet0_mac;+		ar231x_add_ethernet(0, KSEG1ADDR(AR531X_ENET0),+			AR5312_IRQ_ENET0_INTRS, &ar5312_eth0_data);++		ar5312_eth1_data.macaddr = config->enet1_mac;+		ar231x_add_ethernet(1, KSEG1ADDR(AR531X_ENET1),+			AR5312_IRQ_ENET1_INTRS, &ar5312_eth1_data);++		if (!ar231x_board.radio)+			return 0;++		if ((*((u32 *) radio) & AR531X_RADIO0_MASK) &&+		    (config->flags & BD_WLAN0))+			ar231x_add_wmac(0, AR531X_WLAN0,+				AR5312_IRQ_WLAN0_INTRS);++		break;+	/*+	 * AR2312/3 ethernet uses the PHY of ENET0, but the MAC+	 * of ENET1. Atheros calls it 'twisted' for a reason :)+	 */+	case DEV_TYPE_AR2312:+	case DEV_TYPE_AR2313:+		ar5312_eth1_data.phy_base = ar5312_eth0_data.phy_base;+		ar5312_eth1_data.reset_phy = ar5312_eth0_data.reset_phy;+		ar5312_eth1_data.macaddr = config->enet0_mac;+		ar231x_add_ethernet(0, KSEG1ADDR(AR531X_ENET1),+			AR5312_IRQ_ENET1_INTRS, &ar5312_eth1_data);++		if (!ar231x_board.radio)+			return 0;+		break;+	default:+		break;+	}++	if ((*((u32 *) radio) & AR531X_RADIO1_MASK) &&+	    (config->flags & BD_WLAN1))+		ar231x_add_wmac(1, AR531X_WLAN1,+			AR5312_IRQ_WLAN1_INTRS);++	return 0;+}+++static void ar5312_restart(char *command)+{+	/* reset the system */+	local_irq_disable();+	while(1) {+		ar231x_write_reg(AR531X_RESET, AR531X_RESET_SYSTEM);+	}+}+++/*+ * This table is indexed by bits 5..4 of the CLOCKCTL1 register+ * to determine the predevisor value.+ */+static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = { 1, 2, 4, 5 };+++static int __init+ar5312_cpu_frequency(void)+{+	unsigned int result;+	unsigned int predivide_mask, predivide_shift;+	unsigned int multiplier_mask, multiplier_shift;+	unsigned int clockCtl1, preDivideSelect, preDivisor, multiplier;+	unsigned int doubler_mask;+	u16 devid;++	/* Trust the bootrom's idea of cpu frequency. */+	if ((result = ar231x_read_reg(AR5312_SCRATCH)))+		return result;++	devid = ar231x_read_reg(AR531X_REV);+	devid &= AR531X_REV_MAJ;+	devid >>= AR531X_REV_MAJ_S;+	if (devid == AR531X_REV_MAJ_AR2313) {+		predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;+		predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;+		multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;+		multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;+		doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;+	} else { /* AR5312 and AR2312 */+		predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;+		predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;+		multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;+		multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;+		doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;+	}++	/*+	 * Clocking is derived from a fixed 40MHz input clock.+	 *+	 *  cpuFreq = InputClock * MULT (where MULT is PLL multiplier)+	 *  sysFreq = cpuFreq / 4	   (used for APB clock, serial,+	 *							   flash, Timer, Watchdog Timer)+	 *+	 *  cntFreq = cpuFreq / 2	   (use for CPU count/compare)+	 *+	 * So, for example, with a PLL multiplier of 5, we have+	 *+	 *  cpuFreq = 200MHz+	 *  sysFreq = 50MHz+	 *  cntFreq = 100MHz+	 *+	 * We compute the CPU frequency, based on PLL settings.+	 */++	clockCtl1 = ar231x_read_reg(AR5312_CLOCKCTL1);+	preDivideSelect = (clockCtl1 & predivide_mask) >> predivide_shift;+	preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect];+	multiplier = (clockCtl1 & multiplier_mask) >> multiplier_shift;++	if (clockCtl1 & doubler_mask) {+		multiplier = multiplier << 1;+	}+	return (40000000 / preDivisor) * multiplier;+}++static inline int+ar5312_sys_frequency(void)+{+	return ar5312_cpu_frequency() / 4;+}++void __init+ar5312_time_init(void)+{+	if (!is_5312())+		return;++	mips_hpt_frequency = ar5312_cpu_frequency() / 2;+}+++void __init+ar5312_prom_init(void)+{+	u32 memsize, memcfg, bank0AC, bank1AC;+	u32 devid;++	if (!is_5312())+		return;++	/* Detect memory size */+	memcfg = ar231x_read_reg(AR531X_MEM_CFG1);+	bank0AC = (memcfg & MEM_CFG1_AC0) >> MEM_CFG1_AC0_S;+	bank1AC = (memcfg & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S;+	memsize = (bank0AC ? (1 << (bank0AC+1)) : 0)+	        + (bank1AC ? (1 << (bank1AC+1)) : 0);+	memsize <<= 20;+	add_memory_region(0, memsize, BOOT_MEM_RAM);++	devid = ar231x_read_reg(AR531X_REV);+	devid >>= AR531X_REV_WMAC_MIN_S;+	devid &= AR531X_REV_CHIP;+	ar231x_board.devid = (u16) devid;+	ar231x_gpiodev = &ar5312_gpiodev;+}++void __init+ar5312_plat_setup(void)+{+	if (!is_5312())+		return;++	/* Clear any lingering AHB errors */+	ar231x_read_reg(AR531X_PROCADDR);+	ar231x_read_reg(AR531X_DMAADDR);+	ar231x_write_reg(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);++	_machine_restart = ar5312_restart;+	ar231x_serial_setup(KSEG1ADDR(AR531X_UART0), ar5312_sys_frequency());+}+diff -Nur linux-2.6.37.orig/arch/mips/ar231x/ar5312.h linux-2.6.37/arch/mips/ar231x/ar5312.h--- linux-2.6.37.orig/arch/mips/ar231x/ar5312.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/ar5312.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,38 @@+#ifndef __AR5312_H+#define __AR5312_H++#ifdef CONFIG_ATHEROS_AR5312++extern void ar5312_irq_init(void);+extern int ar5312_init_devices(void);+extern void ar5312_prom_init(void);+extern void ar5312_plat_setup(void);+extern void ar5312_time_init(void);+extern void ar5312_time_init(void);++#else++static inline void ar5312_irq_init(void)+{+}++static inline int ar5312_init_devices(void)+{+	return 0;+}++static inline void ar5312_prom_init(void)+{+}++static inline void ar5312_plat_setup(void)+{+}++static inline void ar5312_time_init(void)+{+}++#endif++#endifdiff -Nur linux-2.6.37.orig/arch/mips/ar231x/board.c linux-2.6.37/arch/mips/ar231x/board.c--- linux-2.6.37.orig/arch/mips/ar231x/board.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/board.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,251 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ */++#include <generated/autoconf.h>+#include <linux/init.h>+#include <linux/module.h>+#include <linux/types.h>+#include <linux/string.h>+#include <linux/platform_device.h>+#include <linux/kernel.h>+#include <linux/random.h>+#include <linux/etherdevice.h>+#include <asm/irq_cpu.h>+#include <asm/reboot.h>+#include <asm/io.h>++#include <ar231x_platform.h>+#include "devices.h"+#include "ar5312.h"+#include "ar2315.h"++void (*ar231x_irq_dispatch)(void);++static inline bool+check_radio_magic(u8 *addr)+{+	addr += 0x7a; /* offset for flash magic */+	if ((addr[0] == 0x5a) && (addr[1] == 0xa5)) {+		return 1;+	}+	return 0;+}++static inline bool+check_board_data(u8 *flash_limit, u8 *addr, bool broken)+{+	/* config magic found */+	if (*((u32 *)addr) == AR531X_BD_MAGIC)+		return 1;++	if (!broken)+		return 0;++	if (check_radio_magic(addr + 0xf8))+		ar231x_board.radio = addr + 0xf8;+	if ((addr < flash_limit + 0x10000) &&+	     check_radio_magic(addr + 0x10000))+		ar231x_board.radio = addr + 0x10000;++	if (ar231x_board.radio) {+		/* broken board data detected, use radio data to find the offset,+		 * user will fix this */+		return 1;+	}+	return 0;+}++static u8 *+find_board_config(u8 *flash_limit, bool broken)+{+	u8 *addr;+	int found = 0;++	for (addr = flash_limit - 0x1000;+		addr >= flash_limit - 0x30000;+		addr -= 0x1000) {++		if (check_board_data(flash_limit, addr, broken)) {+			found = 1;+			break;+		}+	}++	if (!found)+		addr = NULL;++	return addr;+}++static u8 *+find_radio_config(u8 *flash_limit, u8 *board_config)+{+	int found;+	u8 *radio_config;++	/*+	 * Now find the start of Radio Configuration data, using heuristics:+	 * Search forward from Board Configuration data by 0x1000 bytes+	 * at a time until we find non-0xffffffff.+	 */+	found = 0;+	for (radio_config = board_config + 0x1000;+	     (radio_config < flash_limit);+	     radio_config += 0x1000) {+		if ((*(u32 *)radio_config != 0xffffffff) &&+		    check_radio_magic(radio_config)) {+			found = 1;+			break;+		}+	}++	/* AR2316 relocates radio config to new location */+	if (!found) {+	    for (radio_config = board_config + 0xf8;+			(radio_config < flash_limit - 0x1000 + 0xf8);+			 radio_config += 0x1000) {+			if ((*(u32 *)radio_config != 0xffffffff) &&+				check_radio_magic(radio_config)) {+				found = 1;+				break;+			}+	    }+	}++	if (!found) {+		printk("Could not find Radio Configuration data\n");+		radio_config = 0;+	}++	return (u8 *) radio_config;+}++int __init+ar231x_find_config(u8 *flash_limit)+{+	struct ar231x_boarddata *config;+	unsigned int rcfg_size;+	int broken_boarddata = 0;+	u8 *bcfg, *rcfg;+	u8 *board_data;+	u8 *radio_data;+	u32 offset;++	ar231x_board.config = NULL;+	ar231x_board.radio = NULL;+	/* Copy the board and radio data to RAM, because accessing the mapped+	 * memory of the flash directly after booting is not safe */++	/* Try to find valid board and radio data */+	bcfg = find_board_config(flash_limit, false);++	/* If that fails, try to at least find valid radio data */+	if (!bcfg) {+		bcfg = find_board_config(flash_limit, true);+		broken_boarddata = 1;+	}++	if (!bcfg) {+		printk(KERN_WARNING "WARNING: No board configuration data found!\n");+		return -ENODEV;+	}++	board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);+	ar231x_board.config = (struct ar231x_boarddata *) board_data;+	memcpy(board_data, bcfg, 0x100);+	if (broken_boarddata) {+		printk(KERN_WARNING "WARNING: broken board data detected\n");+		config = ar231x_board.config;+		if (!memcmp(config->enet0_mac, "\x00\x00\x00\x00\x00\x00", 6)) {+			printk(KERN_INFO "Fixing up empty mac addresses\n");+			config->resetConfigGpio = 0xffff;+			config->sysLedGpio = 0xffff;+			random_ether_addr(config->wlan0_mac);+			config->wlan0_mac[0] &= ~0x06;+			random_ether_addr(config->enet0_mac);+			random_ether_addr(config->enet1_mac);+		}+	}+++	/* Radio config starts 0x100 bytes after board config, regardless+	 * of what the physical layout on the flash chip looks like */++	if (ar231x_board.radio)+		rcfg = (u8 *) ar231x_board.radio;+	else+		rcfg = find_radio_config(flash_limit, bcfg);++	if (!rcfg)+		return -ENODEV;++	radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);+	ar231x_board.radio = radio_data;+	offset = radio_data - board_data;+	printk(KERN_INFO "Radio config found at offset 0x%x(0x%x)\n", rcfg - bcfg, offset);+	rcfg_size = BOARD_CONFIG_BUFSZ - offset;+	memcpy(radio_data, rcfg, rcfg_size);++	return 0;+}++static void+ar231x_halt(void)+{+	local_irq_disable();+	while (1);+}++void __init+plat_mem_setup(void)+{+	_machine_halt = ar231x_halt;+	pm_power_off = ar231x_halt;++	ar5312_plat_setup();+	ar2315_plat_setup();++	/* Disable data watchpoints */+	write_c0_watchlo0(0);+}+++asmlinkage void+plat_irq_dispatch(void)+{+	ar231x_irq_dispatch();+}++void __init+plat_time_init(void)+{+	ar5312_time_init();+	ar2315_time_init();+}++unsigned int __cpuinit+get_c0_compare_int(void)+{+	return CP0_LEGACY_COMPARE_IRQ;+}++void __init+arch_init_irq(void)+{+	clear_c0_status(ST0_IM);+	mips_cpu_irq_init();++	/* Initialize interrupt controllers */+	ar5312_irq_init();+	ar2315_irq_init();+}++diff -Nur linux-2.6.37.orig/arch/mips/ar231x/devices.c linux-2.6.37/arch/mips/ar231x/devices.c--- linux-2.6.37.orig/arch/mips/ar231x/devices.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/devices.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,175 @@+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/serial.h>+#include <linux/serial_core.h>+#include <linux/serial_8250.h>+#include <linux/platform_device.h>+#include <ar231x_platform.h>+#include <ar231x.h>+#include "devices.h"+#include "ar5312.h"+#include "ar2315.h"++struct ar231x_board_config ar231x_board;+int ar231x_devtype = DEV_TYPE_UNKNOWN;+const struct ar231x_gpiodev *ar231x_gpiodev;+EXPORT_SYMBOL(ar231x_gpiodev);++static struct resource ar231x_eth0_res[] = {+	{+		.name = "eth0_membase",+		.flags = IORESOURCE_MEM,+	},+	{+		.name = "eth0_irq",+		.flags = IORESOURCE_IRQ,+	}+};++static struct resource ar231x_eth1_res[] = {+	{+		.name = "eth1_membase",+		.flags = IORESOURCE_MEM,+	},+	{+		.name = "eth1_irq",+		.flags = IORESOURCE_IRQ,+	}+};++static struct platform_device ar231x_eth[] = {+	{+		.id = 0,+		.name = "ar231x-eth",+		.resource = ar231x_eth0_res,+		.num_resources = ARRAY_SIZE(ar231x_eth0_res)+	},+	{+		.id = 1,+		.name = "ar231x-eth",+		.resource = ar231x_eth1_res,+		.num_resources = ARRAY_SIZE(ar231x_eth1_res)+	}+};++static struct resource ar231x_wmac0_res[] = {+	{+		.name = "wmac0_membase",+		.flags = IORESOURCE_MEM,+	},+	{+		.name = "wmac0_irq",+		.flags = IORESOURCE_IRQ,+	}+};++static struct resource ar231x_wmac1_res[] = {+	{+		.name = "wmac1_membase",+		.flags = IORESOURCE_MEM,+	},+	{+		.name = "wmac1_irq",+		.flags = IORESOURCE_IRQ,+	}+};+++static struct platform_device ar231x_wmac[] = {+	{+		.id = 0,+		.name = "ar231x-wmac",+		.resource = ar231x_wmac0_res,+		.num_resources = ARRAY_SIZE(ar231x_wmac0_res),+		.dev.platform_data = &ar231x_board,+	},+	{+		.id = 1,+		.name = "ar231x-wmac",+		.resource = ar231x_wmac1_res,+		.num_resources = ARRAY_SIZE(ar231x_wmac1_res),+		.dev.platform_data = &ar231x_board,+	},+};++static const char *devtype_strings[] = {+	[DEV_TYPE_AR5312] = "Atheros AR5312",+	[DEV_TYPE_AR2312] = "Atheros AR2312",+	[DEV_TYPE_AR2313] = "Atheros AR2313",+	[DEV_TYPE_AR2315] = "Atheros AR2315",+	[DEV_TYPE_AR2316] = "Atheros AR2316",+	[DEV_TYPE_AR2317] = "Atheros AR2317",+	[DEV_TYPE_UNKNOWN] = "Atheros (unknown)",+};++const char *get_system_type(void)+{+	if ((ar231x_devtype >= ARRAY_SIZE(devtype_strings)) ||+		!devtype_strings[ar231x_devtype])+		return devtype_strings[DEV_TYPE_UNKNOWN];+	return devtype_strings[ar231x_devtype];+}+++int __init+ar231x_add_ethernet(int nr, u32 base, int irq, void *pdata)+{+	struct resource *res;++	ar231x_eth[nr].dev.platform_data = pdata;+	res = &ar231x_eth[nr].resource[0];+	res->start = base;+	res->end = base + 0x2000 - 1;+	res++;+	res->start = irq;+	res->end = irq;+	return platform_device_register(&ar231x_eth[nr]);+}++void __init+ar231x_serial_setup(u32 mapbase, unsigned int uartclk)+{+	struct uart_port s;++	memset(&s, 0, sizeof(s));++	s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;+	s.iotype = UPIO_MEM;+	s.irq = AR531X_MISC_IRQ_UART0;+	s.regshift = 2;+	s.mapbase = mapbase;+	s.uartclk = uartclk;+	s.membase = (void __iomem *)s.mapbase;++	early_serial_setup(&s);+}++int __init+ar231x_add_wmac(int nr, u32 base, int irq)+{+	struct resource *res;++	ar231x_wmac[nr].dev.platform_data = &ar231x_board;+	res = &ar231x_wmac[nr].resource[0];+	res->start = base;+	res->end = base + 0x10000 - 1;+	res++;+	res->start = irq;+	res->end = irq;+	return platform_device_register(&ar231x_wmac[nr]);+}++static int __init ar231x_register_devices(void)+{+	static struct resource res = {+		.start = 0xFFFFFFFF,+	};++	platform_device_register_simple("GPIODEV", 0, &res, 1);+	ar5312_init_devices();+	ar2315_init_devices();++	return 0;+}++device_initcall(ar231x_register_devices);diff -Nur linux-2.6.37.orig/arch/mips/ar231x/devices.h linux-2.6.37/arch/mips/ar231x/devices.h--- linux-2.6.37.orig/arch/mips/ar231x/devices.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/devices.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,37 @@+#ifndef __AR231X_DEVICES_H+#define __AR231X_DEVICES_H++enum {+	/* handled by ar5312.c */+	DEV_TYPE_AR2312,+	DEV_TYPE_AR2313,+	DEV_TYPE_AR5312,++	/* handled by ar2315.c */+	DEV_TYPE_AR2315,+	DEV_TYPE_AR2316,+	DEV_TYPE_AR2317,++	DEV_TYPE_UNKNOWN+};++extern int ar231x_devtype;+extern struct ar231x_board_config ar231x_board;+extern asmlinkage void (*ar231x_irq_dispatch)(void);++extern int ar231x_find_config(u8 *flash_limit);+extern void ar231x_serial_setup(u32 mapbase, unsigned int uartclk);+extern int ar231x_add_wmac(int nr, u32 base, int irq);+extern int ar231x_add_ethernet(int nr, u32 base, int irq, void *pdata);++static inline bool is_2315(void)+{+	return (current_cpu_data.cputype == CPU_4KEC);+}++static inline bool is_5312(void)+{+	return !is_2315();+}++#endifdiff -Nur linux-2.6.37.orig/arch/mips/ar231x/early_printk.c linux-2.6.37/arch/mips/ar231x/early_printk.c--- linux-2.6.37.orig/arch/mips/ar231x/early_printk.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/early_printk.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,44 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>+ */++#include <linux/mm.h>+#include <linux/io.h>+#include <linux/serial_reg.h>+#include <asm/addrspace.h>++#include <asm/mach-ar231x/ar2315_regs.h>+#include <asm/mach-ar231x/ar5312_regs.h>+#include "devices.h"++static inline void prom_uart_wr(void __iomem *base, unsigned reg,+				unsigned char ch)+{+	__raw_writeb(ch, base + 4 * reg);+}++static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg)+{+	return __raw_readb(base + 4 * reg);+}++void prom_putchar(unsigned char ch)+{+	static void __iomem *base;++	if (unlikely(base == NULL)) {+		if (is_2315())+			base = (void __iomem *)(KSEG1ADDR(AR2315_UART0));+		else+			base = (void __iomem *)(KSEG1ADDR(AR531X_UART0));+	}++	while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0);+	prom_uart_wr(base, UART_TX, ch);+	while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0);+}+diff -Nur linux-2.6.37.orig/arch/mips/ar231x/pci.c linux-2.6.37/arch/mips/ar231x/pci.c--- linux-2.6.37.orig/arch/mips/ar231x/pci.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/pci.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,230 @@+/*+ * This program is free software; you can redistribute it and/or+ * modify it under the terms of the GNU General Public License+ * as published by the Free Software Foundation; either version 2+ * of the License, or (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.+ */++#include <linux/types.h>+#include <linux/pci.h>+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/mm.h>+#include <linux/spinlock.h>+#include <linux/delay.h>+#include <linux/irq.h>+#include <asm/bootinfo.h>+#include <asm/paccess.h>+#include <asm/irq_cpu.h>+#include <asm/io.h>+#include <ar231x_platform.h>+#include <ar231x.h>+#include <ar2315_regs.h>+#include "devices.h"++#define AR531X_MEM_BASE    0x80800000UL+#define AR531X_MEM_SIZE    0x00ffffffUL+#define AR531X_IO_SIZE     0x00007fffUL++static unsigned long configspace;++static int config_access(int devfn, int where, int size, u32 *ptr, bool write)+{+	unsigned long flags;+	int func = PCI_FUNC(devfn);+	int dev = PCI_SLOT(devfn);+	u32 value = 0;+	int err = 0;+	u32 addr;++	if (((dev != 0) && (dev != 3)) || (func > 2))+		return PCIBIOS_DEVICE_NOT_FOUND;++	/* Select Configuration access */+	local_irq_save(flags);+	ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL);+	mb();++	addr = (u32) configspace + (1 << (13 + dev)) + (func << 8) + where;+	if (size == 1)+		addr ^= 0x3;+	else if (size == 2)+		addr ^= 0x2;++	if (write) {+		value = *ptr;+		if (size == 1)+			err = put_dbe(value, (u8 *) addr);+		else if (size == 2)+			err = put_dbe(value, (u16 *) addr);+		else if (size == 4)+			err = put_dbe(value, (u32 *) addr);+	} else {+		if (size == 1)+			err = get_dbe(value, (u8 *) addr);+		else if (size == 2)+			err = get_dbe(value, (u16 *) addr);+		else if (size == 4)+			err = get_dbe(value, (u32 *) addr);+		if (err)+			*ptr = 0xffffffff;+		else+			*ptr = value;+	}++	/* Select Memory access */+	ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0);+	local_irq_restore(flags);++	return (err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL);+}++static int ar231x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value)+{+	return config_access(devfn, where, size, value, 0);+}++static int ar231x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)+{+	return config_access(devfn, where, size, &value, 1);+}++struct pci_ops ar231x_pci_ops = {+	.read	= ar231x_pci_read,+	.write	= ar231x_pci_write,+};++static struct resource ar231x_mem_resource = {+	.name	= "AR531x PCI MEM",+	.start	= AR531X_MEM_BASE,+	.end	= AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE - 1 + 0x4000000,+	.flags	= IORESOURCE_MEM,+};++static struct resource ar231x_io_resource = {+	.name	= "AR531x PCI I/O",+	.start	= AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE,+	.end	= AR531X_MEM_BASE + AR531X_MEM_SIZE - 1,+	.flags	= IORESOURCE_IO,+};++struct pci_controller ar231x_pci_controller = {+	.pci_ops		= &ar231x_pci_ops,+	.mem_resource	= &ar231x_mem_resource,+	.io_resource	= &ar231x_io_resource,+	.mem_offset     = 0x00000000UL,+	.io_offset      = 0x00000000UL,+};++int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)+{+	return AR2315_IRQ_LCBUS_PCI;+}++int pcibios_plat_dev_init(struct pci_dev *dev)+{+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 5);+	pci_write_config_word(dev, 0x40, 0);++	/* Clear any pending Abort or external Interrupts+	 * and enable interrupt processing */+	ar231x_mask_reg(AR2315_PCI_INTEN_REG, AR2315_PCI_INT_ENABLE, 0);+	ar231x_write_reg(AR2315_PCI_INT_STATUS, (AR2315_PCI_ABORT_INT | AR2315_PCI_EXT_INT));+	ar231x_write_reg(AR2315_PCI_INT_MASK, (AR2315_PCI_ABORT_INT | AR2315_PCI_EXT_INT));+	ar231x_mask_reg(AR2315_PCI_INTEN_REG, 0, AR2315_PCI_INT_ENABLE);++	return 0;+}++static void+ar2315_pci_fixup(struct pci_dev *dev)+{+	unsigned int devfn = dev->devfn;++	if (dev->bus->number != 0)+		return;++	/* Only fix up the PCI host settings */+	if ((PCI_SLOT(devfn) != 3) || (PCI_FUNC(devfn) != 0))+		return;++	/* Fix up MBARs */+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, HOST_PCI_MBAR0);+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, HOST_PCI_MBAR1);+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, HOST_PCI_MBAR2);+	pci_write_config_dword(dev, PCI_COMMAND,+		PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL |+		PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR |+		PCI_COMMAND_FAST_BACK);+}+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, ar2315_pci_fixup);++static int __init+ar2315_pci_init(void)+{+	u32 reg;++	if (ar231x_devtype != DEV_TYPE_AR2315)+		return -ENODEV;++	configspace = (unsigned long) ioremap_nocache(0x80000000, 1*1024*1024); /* Remap PCI config space */+	ar231x_pci_controller.io_map_base =+		(unsigned long) ioremap_nocache(AR531X_MEM_BASE + AR531X_MEM_SIZE, AR531X_IO_SIZE);+	set_io_port_base(ar231x_pci_controller.io_map_base); /* PCI I/O space */++	reg = ar231x_mask_reg(AR2315_RESET, 0, AR2315_RESET_PCIDMA);+	msleep(10);++	reg &= ~AR2315_RESET_PCIDMA;+	ar231x_write_reg(AR2315_RESET, reg);+	msleep(10);++	ar231x_mask_reg(AR2315_ENDIAN_CTL, 0,+		AR2315_CONFIG_PCIAHB | AR2315_CONFIG_PCIAHB_BRIDGE);++	ar231x_write_reg(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM |+		(AR2315_PCICLK_IN_FREQ_DIV_6 << AR2315_PCICLK_DIV_S));+	ar231x_mask_reg(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI);+	ar231x_mask_reg(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | AR2315_IF_MASK,+		AR2315_IF_PCI | AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR |+		 (AR2315_IF_PCI_CLK_OUTPUT_CLK << AR2315_IF_PCI_CLK_SHIFT));++	/* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */+	ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE,+		AR2315_PCIRST_LOW);+	msleep(100);++	/* Bring the PCI out of reset */+	ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE,+		AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8);++	ar231x_write_reg(AR2315_PCI_UNCACHE_CFG,+			0x1E | /* 1GB uncached */+			(1 << 5) | /* Enable uncached */+			(0x2 << 30) /* Base: 0x80000000 */+	);+	ar231x_read_reg(AR2315_PCI_UNCACHE_CFG);++	msleep(500);++	/* dirty hack - anyone with a datasheet that knows the memory map ? */+	ioport_resource.start = 0x10000000;+	ioport_resource.end = 0xffffffff;+	iomem_resource.start = 0x10000000;+	iomem_resource.end = 0xffffffff;++	register_pci_controller(&ar231x_pci_controller);++	return 0;+}++arch_initcall(ar2315_pci_init);diff -Nur linux-2.6.37.orig/arch/mips/ar231x/prom.c linux-2.6.37/arch/mips/ar231x/prom.c--- linux-2.6.37.orig/arch/mips/ar231x/prom.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/prom.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,37 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright MontaVista Software Inc+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>+ */++/*+ * Prom setup file for ar531x+ */++#include <linux/init.h>+#include <generated/autoconf.h>+#include <linux/kernel.h>+#include <linux/string.h>+#include <linux/mm.h>+#include <linux/bootmem.h>++#include <asm/bootinfo.h>+#include <asm/addrspace.h>+#include "ar5312.h"+#include "ar2315.h"++void __init prom_init(void)+{+	ar5312_prom_init();+	ar2315_prom_init();+}++void __init prom_free_prom_memory(void)+{+}diff -Nur linux-2.6.37.orig/arch/mips/ar231x/reset.c linux-2.6.37/arch/mips/ar231x/reset.c--- linux-2.6.37.orig/arch/mips/ar231x/reset.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/ar231x/reset.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,161 @@+#include <linux/init.h>+#include <linux/module.h>+#include <linux/timer.h>+#include <linux/interrupt.h>+#include <linux/kobject.h>+#include <linux/workqueue.h>+#include <linux/skbuff.h>+#include <linux/netlink.h>+#include <net/sock.h>+#include <asm/uaccess.h>+#include <ar231x_platform.h>+#include <ar231x.h>+#include <gpio.h>+#include "devices.h"++#define AR531X_RESET_GPIO_IRQ	(AR531X_GPIO_IRQ(ar231x_board.config->resetConfigGpio))++struct event_t {+	struct work_struct wq;+	int set;+	unsigned long jiffies;+};++static struct timer_list rst_button_timer;+static unsigned long seen;++struct sock *uevent_sock = NULL;+EXPORT_SYMBOL_GPL(uevent_sock);+extern u64 uevent_next_seqnum(void);++static int no_release_workaround = 1;+module_param(no_release_workaround, int, 0);++static inline void+add_msg(struct sk_buff *skb, char *msg)+{+	char *scratch;+	scratch = skb_put(skb, strlen(msg) + 1);+	sprintf(scratch, msg);+}++static void+hotplug_button(struct work_struct *wq)+{+	struct sk_buff *skb;+	struct event_t *event;+	size_t len;+	char *scratch, *s;+	char buf[128];++	event = container_of(wq, struct event_t, wq);+	if (!uevent_sock)+		goto done;++	/* allocate message with the maximum possible size */+	s = event->set ? "pressed" : "released";+	len = strlen(s) + 2;+	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);+	if (!skb)+		goto done;++	/* add header */+	scratch = skb_put(skb, len);+	sprintf(scratch, "%s@",s);++	/* copy keys to our continuous event payload buffer */+	add_msg(skb, "HOME=/");+	add_msg(skb, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");+	add_msg(skb, "SUBSYSTEM=button");+	add_msg(skb, "BUTTON=reset");+	add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released"));+	sprintf(buf, "SEEN=%ld", (event->jiffies - seen)/HZ);+	add_msg(skb, buf);+	snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum());+	add_msg(skb, buf);++	NETLINK_CB(skb).dst_group = 1;+	netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);++done:+	kfree(event);+}++static void+reset_button_poll(unsigned long unused)+{+	struct event_t *event;+	int gpio = ~0;++	if(!no_release_workaround)+		return;++	gpio = ar231x_gpiodev->get();+	gpio &= (1 << (AR531X_RESET_GPIO_IRQ - AR531X_GPIO_IRQ_BASE));+	if(gpio) {+		rst_button_timer.expires = jiffies + (HZ / 4);+		add_timer(&rst_button_timer);+		return;+	}++	event = (struct event_t *) kzalloc(sizeof(struct event_t), GFP_ATOMIC);+	if (!event)+		return;++	event->set = 0;+	event->jiffies = jiffies;+	INIT_WORK(&event->wq, hotplug_button);+	schedule_work(&event->wq);+}++static irqreturn_t+button_handler(int irq, void *dev_id)+{+	static int pressed = 0;+	struct event_t *event;+	u32 gpio = ~0;++	event = (struct event_t *) kzalloc(sizeof(struct event_t), GFP_ATOMIC);+	if (!event)+		return IRQ_NONE;++	pressed = !pressed;++	gpio = ar231x_gpiodev->get() & (1 << (irq - AR531X_GPIO_IRQ_BASE));++	event->set = gpio;+	if(!event->set)+		no_release_workaround = 0;++	event->jiffies = jiffies;++	INIT_WORK(&event->wq, hotplug_button);+	schedule_work(&event->wq);++	seen = jiffies;+	if(event->set && no_release_workaround)+		mod_timer(&rst_button_timer, jiffies + (HZ / 4));++	return IRQ_HANDLED;+}+++static int __init+ar231x_init_reset(void)+{+	seen = jiffies;++	if (ar231x_board.config->resetConfigGpio == 0xffff)+		return -ENODEV;++	init_timer(&rst_button_timer);+	rst_button_timer.function = reset_button_poll;+	rst_button_timer.expires = jiffies + HZ / 50;+	add_timer(&rst_button_timer);++	request_irq(AR531X_RESET_GPIO_IRQ, &button_handler, IRQF_SAMPLE_RANDOM, "ar231x_reset", NULL);++	return 0;+}++module_init(ar231x_init_reset);diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar2315_regs.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar2315_regs.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar2315_regs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar2315_regs.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,580 @@+/*+ * Register definitions for AR2315++ *+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org>+ */++#ifndef __AR2315_REG_H+#define __AR2315_REG_H++/*+ * IRQs+ */+#define AR2315_IRQ_MISC_INTRS   MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */+#define AR2315_IRQ_WLAN0_INTRS  MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */+#define AR2315_IRQ_ENET0_INTRS  MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */+#define AR2315_IRQ_LCBUS_PCI    MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */+#define AR2315_IRQ_WLAN0_POLL   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */++/*+ * Address map+ */+#define AR2315_SPI_READ         0x08000000      /* SPI FLASH */+#define AR2315_WLAN0            0xB0000000      /* Wireless MMR */+#define AR2315_PCI              0xB0100000      /* PCI MMR */+#define AR2315_SDRAMCTL         0xB0300000      /* SDRAM MMR */+#define AR2315_LOCAL            0xB0400000      /* LOCAL BUS MMR */+#define AR2315_ENET0            0xB0500000      /* ETHERNET MMR */+#define AR2315_DSLBASE          0xB1000000      /* RESET CONTROL MMR */+#define AR2315_UART0            0xB1100003      /* UART MMR */+#define AR2315_SPI              0xB1300000      /* SPI FLASH MMR */+#define AR2315_PCIEXT           0x80000000      /* pci external */++/*+ * Reset Register+ */+#define AR2315_COLD_RESET       (AR2315_DSLBASE + 0x0000)++#define AR2315_RESET_COLD_AHB              0x00000001+#define AR2315_RESET_COLD_APB              0x00000002+#define AR2315_RESET_COLD_CPU              0x00000004+#define AR2315_RESET_COLD_CPUWARM          0x00000008+#define AR2315_RESET_SYSTEM                (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB)      /* full system */+#define AR2317_RESET_SYSTEM                0x00000010+++#define AR2315_RESET            (AR2315_DSLBASE + 0x0004)++#define AR2315_RESET_WARM_WLAN0_MAC        0x00000001      /* warm reset WLAN0 MAC */+#define AR2315_RESET_WARM_WLAN0_BB         0x00000002      /* warm reset WLAN0 BaseBand */+#define AR2315_RESET_MPEGTS_RSVD           0x00000004      /* warm reset MPEG-TS */+#define AR2315_RESET_PCIDMA                0x00000008      /* warm reset PCI ahb/dma */+#define AR2315_RESET_MEMCTL                0x00000010      /* warm reset memory controller */+#define AR2315_RESET_LOCAL                 0x00000020      /* warm reset local bus */+#define AR2315_RESET_I2C_RSVD              0x00000040      /* warm reset I2C bus */+#define AR2315_RESET_SPI                   0x00000080      /* warm reset SPI interface */+#define AR2315_RESET_UART0                 0x00000100      /* warm reset UART0 */+#define AR2315_RESET_IR_RSVD               0x00000200      /* warm reset IR interface */+#define AR2315_RESET_EPHY0                 0x00000400      /* cold reset ENET0 phy */+#define AR2315_RESET_ENET0                 0x00000800      /* cold reset ENET0 mac */++/*+ * AHB master arbitration control+ */+#define AR2315_AHB_ARB_CTL      (AR2315_DSLBASE + 0x0008)++#define AR2315_ARB_CPU                     0x00000001      /* CPU, default */+#define AR2315_ARB_WLAN                    0x00000002      /* WLAN */+#define AR2315_ARB_MPEGTS_RSVD             0x00000004      /* MPEG-TS */+#define AR2315_ARB_LOCAL                   0x00000008      /* LOCAL */+#define AR2315_ARB_PCI                     0x00000010      /* PCI */+#define AR2315_ARB_ETHERNET                0x00000020      /* Ethernet */+#define AR2315_ARB_RETRY                   0x00000100      /* retry policy, debug only */++/*+ * Config Register+ */+#define AR2315_ENDIAN_CTL       (AR2315_DSLBASE + 0x000c)++#define AR2315_CONFIG_AHB                  0x00000001      /* EC - AHB bridge endianess */+#define AR2315_CONFIG_WLAN                 0x00000002      /* WLAN byteswap */+#define AR2315_CONFIG_MPEGTS_RSVD          0x00000004      /* MPEG-TS byteswap */+#define AR2315_CONFIG_PCI                  0x00000008      /* PCI byteswap */+#define AR2315_CONFIG_MEMCTL               0x00000010      /* Memory controller endianess */+#define AR2315_CONFIG_LOCAL                0x00000020      /* Local bus byteswap */+#define AR2315_CONFIG_ETHERNET             0x00000040      /* Ethernet byteswap */++#define AR2315_CONFIG_MERGE                0x00000200      /* CPU write buffer merge */+#define AR2315_CONFIG_CPU                  0x00000400      /* CPU big endian */+#define AR2315_CONFIG_PCIAHB               0x00000800+#define AR2315_CONFIG_PCIAHB_BRIDGE        0x00001000+#define AR2315_CONFIG_SPI                  0x00008000      /* SPI byteswap */+#define AR2315_CONFIG_CPU_DRAM             0x00010000+#define AR2315_CONFIG_CPU_PCI              0x00020000+#define AR2315_CONFIG_CPU_MMR              0x00040000+#define AR2315_CONFIG_BIG                  0x00000400+++/*+ * NMI control+ */+#define AR2315_NMI_CTL          (AR2315_DSLBASE + 0x0010)++#define AR2315_NMI_EN  1++/*+ * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0).+ */+#define AR2315_SREV             (AR2315_DSLBASE + 0x0014)++#define AR2315_REV_MAJ                     0x00f0+#define AR2315_REV_MAJ_S                   4+#define AR2315_REV_MIN                     0x000f+#define AR2315_REV_MIN_S                   0+#define AR2315_REV_CHIP                    (AR2315_REV_MAJ|AR2315_REV_MIN)++/*+ * Interface Enable+ */+#define AR2315_IF_CTL           (AR2315_DSLBASE + 0x0018)++#define AR2315_IF_MASK                     0x00000007+#define AR2315_IF_DISABLED                 0+#define AR2315_IF_PCI                      1+#define AR2315_IF_TS_LOCAL                 2+#define AR2315_IF_ALL                      3   /* only for emulation with separate pins */+#define AR2315_IF_LOCAL_HOST               0x00000008+#define AR2315_IF_PCI_HOST                 0x00000010+#define AR2315_IF_PCI_INTR                 0x00000020+#define AR2315_IF_PCI_CLK_MASK             0x00030000+#define AR2315_IF_PCI_CLK_INPUT            0+#define AR2315_IF_PCI_CLK_OUTPUT_LOW       1+#define AR2315_IF_PCI_CLK_OUTPUT_CLK       2+#define AR2315_IF_PCI_CLK_OUTPUT_HIGH      3+#define AR2315_IF_PCI_CLK_SHIFT            16++/*+ * APB Interrupt control+ */++#define AR2315_ISR              (AR2315_DSLBASE + 0x0020)+#define AR2315_IMR              (AR2315_DSLBASE + 0x0024)+#define AR2315_GISR             (AR2315_DSLBASE + 0x0028)++#define AR2315_ISR_UART0                   0x0001           /* high speed UART */+#define AR2315_ISR_I2C_RSVD                0x0002           /* I2C bus */+#define AR2315_ISR_SPI                     0x0004           /* SPI bus */+#define AR2315_ISR_AHB                     0x0008           /* AHB error */+#define AR2315_ISR_APB                     0x0010           /* APB error */+#define AR2315_ISR_TIMER                   0x0020           /* timer */+#define AR2315_ISR_GPIO                    0x0040           /* GPIO */+#define AR2315_ISR_WD                      0x0080           /* watchdog */+#define AR2315_ISR_IR_RSVD                 0x0100           /* IR */++#define AR2315_GISR_MISC                   0x0001+#define AR2315_GISR_WLAN0                  0x0002+#define AR2315_GISR_MPEGTS_RSVD            0x0004+#define AR2315_GISR_LOCALPCI               0x0008+#define AR2315_GISR_WMACPOLL               0x0010+#define AR2315_GISR_TIMER                  0x0020+#define AR2315_GISR_ETHERNET               0x0040++/*+ * Interrupt routing from IO to the processor IP bits+ * Define our inter mask and level+ */+#define AR2315_INTR_MISCIO      SR_IBIT3+#define AR2315_INTR_WLAN0       SR_IBIT4+#define AR2315_INTR_ENET0       SR_IBIT5+#define AR2315_INTR_LOCALPCI    SR_IBIT6+#define AR2315_INTR_WMACPOLL    SR_IBIT7+#define AR2315_INTR_COMPARE     SR_IBIT8++/*+ * Timers+ */+#define AR2315_TIMER            (AR2315_DSLBASE + 0x0030)+#define AR2315_RELOAD           (AR2315_DSLBASE + 0x0034)+#define AR2315_WD               (AR2315_DSLBASE + 0x0038)+#define AR2315_WDC              (AR2315_DSLBASE + 0x003c)++#define AR2315_WDC_IGNORE_EXPIRATION       0x00000000+#define AR2315_WDC_NMI                     0x00000001               /* NMI on watchdog */+#define AR2315_WDC_RESET                   0x00000002               /* reset on watchdog */++/*+ * CPU Performance Counters+ */+#define AR2315_PERFCNT0         (AR2315_DSLBASE + 0x0048)+#define AR2315_PERFCNT1         (AR2315_DSLBASE + 0x004c)++#define AR2315_PERF0_DATAHIT                0x0001  /* Count Data Cache Hits */+#define AR2315_PERF0_DATAMISS               0x0002  /* Count Data Cache Misses */+#define AR2315_PERF0_INSTHIT                0x0004  /* Count Instruction Cache Hits */+#define AR2315_PERF0_INSTMISS               0x0008  /* Count Instruction Cache Misses */+#define AR2315_PERF0_ACTIVE                 0x0010  /* Count Active Processor Cycles */+#define AR2315_PERF0_WBHIT                  0x0020  /* Count CPU Write Buffer Hits */+#define AR2315_PERF0_WBMISS                 0x0040  /* Count CPU Write Buffer Misses */++#define AR2315_PERF1_EB_ARDY                0x0001  /* Count EB_ARdy signal */+#define AR2315_PERF1_EB_AVALID              0x0002  /* Count EB_AValid signal */+#define AR2315_PERF1_EB_WDRDY               0x0004  /* Count EB_WDRdy signal */+#define AR2315_PERF1_EB_RDVAL               0x0008  /* Count EB_RdVal signal */+#define AR2315_PERF1_VRADDR                 0x0010  /* Count valid read address cycles */+#define AR2315_PERF1_VWADDR                 0x0020  /* Count valid write address cycles */+#define AR2315_PERF1_VWDATA                 0x0040  /* Count valid write data cycles */++/*+ * AHB Error Reporting.+ */+#define AR2315_AHB_ERR0         (AR2315_DSLBASE + 0x0050)  /* error  */+#define AR2315_AHB_ERR1         (AR2315_DSLBASE + 0x0054)  /* haddr  */+#define AR2315_AHB_ERR2         (AR2315_DSLBASE + 0x0058)  /* hwdata */+#define AR2315_AHB_ERR3         (AR2315_DSLBASE + 0x005c)  /* hrdata */+#define AR2315_AHB_ERR4         (AR2315_DSLBASE + 0x0060)  /* status */++#define AHB_ERROR_DET               1   /* AHB Error has been detected,          */+                                        /* write 1 to clear all bits in ERR0     */+#define AHB_ERROR_OVR               2   /* AHB Error overflow has been detected  */+#define AHB_ERROR_WDT               4   /* AHB Error due to wdt instead of hresp */++#define AR2315_PROCERR_HMAST               0x0000000f+#define AR2315_PROCERR_HMAST_DFLT          0+#define AR2315_PROCERR_HMAST_WMAC          1+#define AR2315_PROCERR_HMAST_ENET          2+#define AR2315_PROCERR_HMAST_PCIENDPT      3+#define AR2315_PROCERR_HMAST_LOCAL         4+#define AR2315_PROCERR_HMAST_CPU           5+#define AR2315_PROCERR_HMAST_PCITGT        6++#define AR2315_PROCERR_HMAST_S             0+#define AR2315_PROCERR_HWRITE              0x00000010+#define AR2315_PROCERR_HSIZE               0x00000060+#define AR2315_PROCERR_HSIZE_S             5+#define AR2315_PROCERR_HTRANS              0x00000180+#define AR2315_PROCERR_HTRANS_S            7+#define AR2315_PROCERR_HBURST              0x00000e00+#define AR2315_PROCERR_HBURST_S            9++/*+ * Clock Control+ */+#define AR2315_PLLC_CTL         (AR2315_DSLBASE + 0x0064)+#define AR2315_PLLV_CTL         (AR2315_DSLBASE + 0x0068)+#define AR2315_CPUCLK           (AR2315_DSLBASE + 0x006c)+#define AR2315_AMBACLK          (AR2315_DSLBASE + 0x0070)+#define AR2315_SYNCCLK          (AR2315_DSLBASE + 0x0074)+#define AR2315_DSL_SLEEP_CTL    (AR2315_DSLBASE + 0x0080)+#define AR2315_DSL_SLEEP_DUR    (AR2315_DSLBASE + 0x0084)++/* PLLc Control fields */+#define PLLC_REF_DIV_M              0x00000003+#define PLLC_REF_DIV_S              0+#define PLLC_FDBACK_DIV_M           0x0000007C+#define PLLC_FDBACK_DIV_S           2+#define PLLC_ADD_FDBACK_DIV_M       0x00000080+#define PLLC_ADD_FDBACK_DIV_S       7+#define PLLC_CLKC_DIV_M             0x0001c000+#define PLLC_CLKC_DIV_S             14+#define PLLC_CLKM_DIV_M             0x00700000+#define PLLC_CLKM_DIV_S             20++/* CPU CLK Control fields */+#define CPUCLK_CLK_SEL_M            0x00000003+#define CPUCLK_CLK_SEL_S            0+#define CPUCLK_CLK_DIV_M            0x0000000c+#define CPUCLK_CLK_DIV_S            2++/* AMBA CLK Control fields */+#define AMBACLK_CLK_SEL_M           0x00000003+#define AMBACLK_CLK_SEL_S           0+#define AMBACLK_CLK_DIV_M           0x0000000c+#define AMBACLK_CLK_DIV_S           2++/*+ * GPIO+ */+#define AR2315_GPIO_DI          (AR2315_DSLBASE + 0x0088)+#define AR2315_GPIO_DO          (AR2315_DSLBASE + 0x0090)+#define AR2315_GPIO_CR          (AR2315_DSLBASE + 0x0098)+#define AR2315_GPIO_INT         (AR2315_DSLBASE + 0x00a0)++#define AR2315_GPIO_CR_M(x)                (1 << (x))                  /* mask for i/o */+#define AR2315_GPIO_CR_O(x)                (1 << (x))                  /* output */+#define AR2315_GPIO_CR_I(x)                (0)                         /* input */++#define AR2315_GPIO_INT_S(x)               (x)                         /* interrupt enable */+#define AR2315_GPIO_INT_M                  (0x3F)                      /* mask for int */+#define AR2315_GPIO_INT_LVL(x)             ((x) << 6)                  /* interrupt level */+#define AR2315_GPIO_INT_LVL_M              ((0x3) << 6)                /* mask for int level */++#define AR2315_GPIO_INT_MAX_Y				1   /* Maximum value of Y for AR5313_GPIO_INT_* macros */+#define AR2315_GPIO_INT_LVL_OFF				0   /* Triggerring off */+#define AR2315_GPIO_INT_LVL_LOW				1   /* Low Level Triggered */+#define AR2315_GPIO_INT_LVL_HIGH			2   /* High Level Triggered */+#define AR2315_GPIO_INT_LVL_EDGE			3   /* Edge Triggered */++#define AR2315_RESET_GPIO       5+#define AR2315_NUM_GPIO         22++/*+ *  PCI Clock Control+ */+#define AR2315_PCICLK           (AR2315_DSLBASE + 0x00a4)++#define AR2315_PCICLK_INPUT_M              0x3+#define AR2315_PCICLK_INPUT_S              0++#define AR2315_PCICLK_PLLC_CLKM            0+#define AR2315_PCICLK_PLLC_CLKM1           1+#define AR2315_PCICLK_PLLC_CLKC            2+#define AR2315_PCICLK_REF_CLK              3++#define AR2315_PCICLK_DIV_M                0xc+#define AR2315_PCICLK_DIV_S                2++#define AR2315_PCICLK_IN_FREQ              0+#define AR2315_PCICLK_IN_FREQ_DIV_6        1+#define AR2315_PCICLK_IN_FREQ_DIV_8        2+#define AR2315_PCICLK_IN_FREQ_DIV_10       3++/*+ * Observation Control Register+ */+#define AR2315_OCR              (AR2315_DSLBASE + 0x00b0)+#define OCR_GPIO0_IRIN              0x0040+#define OCR_GPIO1_IROUT             0x0080+#define OCR_GPIO3_RXCLR             0x0200++/*+ *  General Clock Control+ */++#define AR2315_MISCCLK          (AR2315_DSLBASE + 0x00b4)+#define MISCCLK_PLLBYPASS_EN        0x00000001+#define MISCCLK_PROCREFCLK          0x00000002++/*+ * SDRAM Controller+ *   - No read or write buffers are included.+ */+#define AR2315_MEM_CFG          (AR2315_SDRAMCTL + 0x00)+#define AR2315_MEM_CTRL         (AR2315_SDRAMCTL + 0x0c)+#define AR2315_MEM_REF          (AR2315_SDRAMCTL + 0x10)++#define SDRAM_DATA_WIDTH_M          0x00006000+#define SDRAM_DATA_WIDTH_S          13++#define SDRAM_COL_WIDTH_M           0x00001E00+#define SDRAM_COL_WIDTH_S           9++#define SDRAM_ROW_WIDTH_M           0x000001E0+#define SDRAM_ROW_WIDTH_S           5++#define SDRAM_BANKADDR_BITS_M       0x00000018+#define SDRAM_BANKADDR_BITS_S       3++/*+ * SPI Flash Interface Registers+ */++#define AR2315_SPI_CTL      (AR2315_SPI + 0x00)+#define AR2315_SPI_OPCODE   (AR2315_SPI + 0x04)+#define AR2315_SPI_DATA     (AR2315_SPI + 0x08)++#define SPI_CTL_START           0x00000100+#define SPI_CTL_BUSY            0x00010000+#define SPI_CTL_TXCNT_MASK      0x0000000f+#define SPI_CTL_RXCNT_MASK      0x000000f0+#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff+#define SPI_CTL_SIZE_MASK       0x00060000++#define SPI_CTL_CLK_SEL_MASK    0x03000000+#define SPI_OPCODE_MASK         0x000000ff++/*+ * PCI Bus Interface Registers+ */+#define AR2315_PCI_1MS_REG      (AR2315_PCI + 0x0008)+#define AR2315_PCI_1MS_MASK     0x3FFFF         /* # of AHB clk cycles in 1ms */++#define AR2315_PCI_MISC_CONFIG  (AR2315_PCI + 0x000c)+#define AR2315_PCIMISC_TXD_EN   0x00000001      /* Enable TXD for fragments */+#define AR2315_PCIMISC_CFG_SEL  0x00000002      /* mem or config cycles */+#define AR2315_PCIMISC_GIG_MASK 0x0000000C      /* bits 31-30 for pci req */+#define AR2315_PCIMISC_RST_MODE 0x00000030+#define AR2315_PCIRST_INPUT     0x00000000      /* 4:5=0 rst is input */+#define AR2315_PCIRST_LOW       0x00000010      /* 4:5=1 rst to GND */+#define AR2315_PCIRST_HIGH      0x00000020      /* 4:5=2 rst to VDD */+#define AR2315_PCIGRANT_EN      0x00000000      /* 6:7=0 early grant en */+#define AR2315_PCIGRANT_FRAME   0x00000040      /* 6:7=1 grant waits 4 frame */+#define AR2315_PCIGRANT_IDLE    0x00000080      /* 6:7=2 grant waits 4 idle */+#define AR2315_PCIGRANT_GAP     0x00000000      /* 6:7=2 grant waits 4 idle */+#define AR2315_PCICACHE_DIS     0x00001000      /* PCI external access cache disable */++#define AR2315_PCI_OUT_TSTAMP   (AR2315_PCI + 0x0010)++#define AR2315_PCI_UNCACHE_CFG  (AR2315_PCI + 0x0014)++#define AR2315_PCI_IN_EN        (AR2315_PCI + 0x0100)+#define AR2315_PCI_IN_EN0       0x01            /* Enable chain 0 */+#define AR2315_PCI_IN_EN1       0x02            /* Enable chain 1 */+#define AR2315_PCI_IN_EN2       0x04            /* Enable chain 2 */+#define AR2315_PCI_IN_EN3       0x08            /* Enable chain 3 */++#define AR2315_PCI_IN_DIS       (AR2315_PCI + 0x0104)+#define AR2315_PCI_IN_DIS0      0x01            /* Disable chain 0 */+#define AR2315_PCI_IN_DIS1      0x02            /* Disable chain 1 */+#define AR2315_PCI_IN_DIS2      0x04            /* Disable chain 2 */+#define AR2315_PCI_IN_DIS3      0x08            /* Disable chain 3 */++#define AR2315_PCI_IN_PTR       (AR2315_PCI + 0x0200)++#define AR2315_PCI_OUT_EN       (AR2315_PCI + 0x0400)+#define AR2315_PCI_OUT_EN0      0x01            /* Enable chain 0 */++#define AR2315_PCI_OUT_DIS      (AR2315_PCI + 0x0404)+#define AR2315_PCI_OUT_DIS0     0x01            /* Disable chain 0 */++#define AR2315_PCI_OUT_PTR      (AR2315_PCI + 0x0408)++#define AR2315_PCI_INT_STATUS   (AR2315_PCI + 0x0500)   /* write one to clr */+#define AR2315_PCI_TXINT        0x00000001      /* Desc In Completed */+#define AR2315_PCI_TXOK         0x00000002      /* Desc In OK */+#define AR2315_PCI_TXERR        0x00000004      /* Desc In ERR */+#define AR2315_PCI_TXEOL        0x00000008      /* Desc In End-of-List */+#define AR2315_PCI_RXINT        0x00000010      /* Desc Out Completed */+#define AR2315_PCI_RXOK         0x00000020      /* Desc Out OK */+#define AR2315_PCI_RXERR        0x00000040      /* Desc Out ERR */+#define AR2315_PCI_RXEOL        0x00000080      /* Desc Out EOL */+#define AR2315_PCI_TXOOD        0x00000200      /* Desc In Out-of-Desc */+#define AR2315_PCI_MASK         0x0000FFFF      /* Desc Mask */+#define AR2315_PCI_EXT_INT      0x02000000+#define AR2315_PCI_ABORT_INT    0x04000000++#define AR2315_PCI_INT_MASK     (AR2315_PCI + 0x0504)   /* same as INT_STATUS */++#define AR2315_PCI_INTEN_REG    (AR2315_PCI + 0x0508)+#define AR2315_PCI_INT_DISABLE  0x00            /* disable pci interrupts */+#define AR2315_PCI_INT_ENABLE   0x01            /* enable pci interrupts */++#define AR2315_PCI_HOST_IN_EN   (AR2315_PCI + 0x0800)+#define AR2315_PCI_HOST_IN_DIS  (AR2315_PCI + 0x0804)+#define AR2315_PCI_HOST_IN_PTR  (AR2315_PCI + 0x0810)+#define AR2315_PCI_HOST_OUT_EN  (AR2315_PCI + 0x0900)+#define AR2315_PCI_HOST_OUT_DIS (AR2315_PCI + 0x0904)+#define AR2315_PCI_HOST_OUT_PTR (AR2315_PCI + 0x0908)+++/*+ * Local Bus Interface Registers+ */+#define AR2315_LB_CONFIG        (AR2315_LOCAL + 0x0000)+#define AR2315_LBCONF_OE        0x00000001      /* =1 OE is low-true */+#define AR2315_LBCONF_CS0       0x00000002      /* =1 first CS is low-true */+#define AR2315_LBCONF_CS1       0x00000004      /* =1 2nd CS is low-true */+#define AR2315_LBCONF_RDY       0x00000008      /* =1 RDY is low-true */+#define AR2315_LBCONF_WE        0x00000010      /* =1 Write En is low-true */+#define AR2315_LBCONF_WAIT      0x00000020      /* =1 WAIT is low-true */+#define AR2315_LBCONF_ADS       0x00000040      /* =1 Adr Strobe is low-true */+#define AR2315_LBCONF_MOT       0x00000080      /* =0 Intel, =1 Motorola */+#define AR2315_LBCONF_8CS       0x00000100      /* =1 8 bits CS, 0= 16bits */+#define AR2315_LBCONF_8DS       0x00000200      /* =1 8 bits Data S, 0=16bits */+#define AR2315_LBCONF_ADS_EN    0x00000400      /* =1 Enable ADS */+#define AR2315_LBCONF_ADR_OE    0x00000800      /* =1 Adr cap on OE, WE or DS */+#define AR2315_LBCONF_ADDT_MUX  0x00001000      /* =1 Adr and Data share bus */+#define AR2315_LBCONF_DATA_OE   0x00002000      /* =1 Data cap on OE, WE, DS */+#define AR2315_LBCONF_16DATA    0x00004000      /* =1 Data is 16 bits wide */+#define AR2315_LBCONF_SWAPDT    0x00008000      /* =1 Byte swap data */+#define AR2315_LBCONF_SYNC      0x00010000      /* =1 Bus synchronous to clk */+#define AR2315_LBCONF_INT       0x00020000      /* =1 Intr is low true */+#define AR2315_LBCONF_INT_CTR0  0x00000000      /* GND high-Z, Vdd is high-Z */+#define AR2315_LBCONF_INT_CTR1  0x00040000      /* GND drive, Vdd is high-Z */+#define AR2315_LBCONF_INT_CTR2  0x00080000      /* GND high-Z, Vdd drive */+#define AR2315_LBCONF_INT_CTR3  0x000C0000      /* GND drive, Vdd drive */+#define AR2315_LBCONF_RDY_WAIT  0x00100000      /* =1 RDY is negative of WAIT */+#define AR2315_LBCONF_INT_PULSE 0x00200000      /* =1 Interrupt is a pulse */+#define AR2315_LBCONF_ENABLE    0x00400000      /* =1 Falcon respond to LB */++#define AR2315_LB_CLKSEL        (AR2315_LOCAL + 0x0004)+#define AR2315_LBCLK_EXT        0x0001          /* use external clk for lb */++#define AR2315_LB_1MS           (AR2315_LOCAL + 0x0008)+#define AR2315_LB1MS_MASK       0x3FFFF         /* # of AHB clk cycles in 1ms */++#define AR2315_LB_MISCCFG       (AR2315_LOCAL + 0x000C)+#define AR2315_LBM_TXD_EN       0x00000001      /* Enable TXD for fragments */+#define AR2315_LBM_RX_INTEN     0x00000002      /* Enable LB ints on RX ready */+#define AR2315_LBM_MBOXWR_INTEN 0x00000004      /* Enable LB ints on mbox wr */+#define AR2315_LBM_MBOXRD_INTEN 0x00000008      /* Enable LB ints on mbox rd */+#define AR2315_LMB_DESCSWAP_EN  0x00000010      /* Byte swap desc enable */+#define AR2315_LBM_TIMEOUT_MASK 0x00FFFF80+#define AR2315_LBM_TIMEOUT_SHFT 7+#define AR2315_LBM_PORTMUX      0x07000000+++#define AR2315_LB_RXTSOFF       (AR2315_LOCAL + 0x0010)++#define AR2315_LB_TX_CHAIN_EN   (AR2315_LOCAL + 0x0100)+#define AR2315_LB_TXEN_0        0x01+#define AR2315_LB_TXEN_1        0x02+#define AR2315_LB_TXEN_2        0x04+#define AR2315_LB_TXEN_3        0x08++#define AR2315_LB_TX_CHAIN_DIS  (AR2315_LOCAL + 0x0104)+#define AR2315_LB_TX_DESC_PTR   (AR2315_LOCAL + 0x0200)++#define AR2315_LB_RX_CHAIN_EN   (AR2315_LOCAL + 0x0400)+#define AR2315_LB_RXEN          0x01++#define AR2315_LB_RX_CHAIN_DIS  (AR2315_LOCAL + 0x0404)+#define AR2315_LB_RX_DESC_PTR   (AR2315_LOCAL + 0x0408)++#define AR2315_LB_INT_STATUS    (AR2315_LOCAL + 0x0500)+#define AR2315_INT_TX_DESC      0x0001+#define AR2315_INT_TX_OK        0x0002+#define AR2315_INT_TX_ERR       0x0004+#define AR2315_INT_TX_EOF       0x0008+#define AR2315_INT_RX_DESC      0x0010+#define AR2315_INT_RX_OK        0x0020+#define AR2315_INT_RX_ERR       0x0040+#define AR2315_INT_RX_EOF       0x0080+#define AR2315_INT_TX_TRUNC     0x0100+#define AR2315_INT_TX_STARVE    0x0200+#define AR2315_INT_LB_TIMEOUT   0x0400+#define AR2315_INT_LB_ERR       0x0800+#define AR2315_INT_MBOX_WR      0x1000+#define AR2315_INT_MBOX_RD      0x2000++/* Bit definitions for INT MASK are the same as INT_STATUS */+#define AR2315_LB_INT_MASK      (AR2315_LOCAL + 0x0504)++#define AR2315_LB_INT_EN        (AR2315_LOCAL + 0x0508)+#define AR2315_LB_MBOX          (AR2315_LOCAL + 0x0600)++/*+ * IR Interface Registers+ */+#define AR2315_IR_PKTDATA                   (AR2315_IR + 0x0000)++#define AR2315_IR_PKTLEN                    (AR2315_IR + 0x07fc) /* 0 - 63 */++#define AR2315_IR_CONTROL                   (AR2315_IR + 0x0800)+#define AR2315_IRCTL_TX                     0x00000000  /* use as tranmitter */+#define AR2315_IRCTL_RX                     0x00000001  /* use as receiver   */+#define AR2315_IRCTL_SAMPLECLK_MASK         0x00003ffe  /* Sample clk divisor mask */+#define AR2315_IRCTL_SAMPLECLK_SHFT                  1+#define AR2315_IRCTL_OUTPUTCLK_MASK         0x03ffc000  /* Output clk divisor mask */+#define AR2315_IRCTL_OUTPUTCLK_SHFT                 14++#define AR2315_IR_STATUS                    (AR2315_IR + 0x0804)+#define AR2315_IRSTS_RX                     0x00000001  /* receive in progress */+#define AR2315_IRSTS_TX                     0x00000002  /* transmit in progress */++#define AR2315_IR_CONFIG                    (AR2315_IR + 0x0808)+#define AR2315_IRCFG_INVIN                  0x00000001  /* invert input polarity */+#define AR2315_IRCFG_INVOUT                 0x00000002  /* invert output polarity */+#define AR2315_IRCFG_SEQ_START_WIN_SEL      0x00000004  /* 1 => 28, 0 => 7 */+#define AR2315_IRCFG_SEQ_START_THRESH       0x000000f0  /*  */+#define AR2315_IRCFG_SEQ_END_UNIT_SEL       0x00000100  /*  */+#define AR2315_IRCFG_SEQ_END_UNIT_THRESH    0x00007e00  /*  */+#define AR2315_IRCFG_SEQ_END_WIN_SEL        0x00008000  /*  */+#define AR2315_IRCFG_SEQ_END_WIN_THRESH     0x001f0000  /*  */+#define AR2315_IRCFG_NUM_BACKOFF_WORDS      0x01e00000  /*  */++#define HOST_PCI_DEV_ID         3+#define HOST_PCI_MBAR0          0x10000000+#define HOST_PCI_MBAR1          0x20000000+#define HOST_PCI_MBAR2          0x30000000++#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1+#define PCI_DEVICE_MEM_SPACE    0x800000++#endif /* __AR2315_REG_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar2315_spiflash.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar2315_spiflash.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar2315_spiflash.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar2315_spiflash.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,116 @@+/*+ * SPI Flash Memory support header file.+ *+ * Copyright (c) 2005, Atheros Communications Inc.+ * Copyright (C) 2006 FON Technology, SL.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ *+ * This code is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ *+ */+#ifndef __AR2315_SPIFLASH_H+#define __AR2315_SPIFLASH_H++#define STM_PAGE_SIZE           256++#define SFI_WRITE_BUFFER_SIZE   4+#define SFI_FLASH_ADDR_MASK     0x00ffffff++#define STM_8MBIT_SIGNATURE     0x13+#define STM_M25P80_BYTE_COUNT   1048576+#define STM_M25P80_SECTOR_COUNT 16+#define STM_M25P80_SECTOR_SIZE  0x10000++#define STM_16MBIT_SIGNATURE    0x14+#define STM_M25P16_BYTE_COUNT   2097152+#define STM_M25P16_SECTOR_COUNT 32+#define STM_M25P16_SECTOR_SIZE  0x10000++#define STM_32MBIT_SIGNATURE    0x15+#define STM_M25P32_BYTE_COUNT   4194304+#define STM_M25P32_SECTOR_COUNT 64+#define STM_M25P32_SECTOR_SIZE  0x10000++#define STM_64MBIT_SIGNATURE    0x16+#define STM_M25P64_BYTE_COUNT   8388608+#define STM_M25P64_SECTOR_COUNT 128+#define STM_M25P64_SECTOR_SIZE  0x10000++#define STM_128MBIT_SIGNATURE   0x17+#define STM_M25P128_BYTE_COUNT   16777216+#define STM_M25P128_SECTOR_COUNT 256+#define STM_M25P128_SECTOR_SIZE  0x10000++#define STM_1MB_BYTE_COUNT   STM_M25P80_BYTE_COUNT+#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT+#define STM_1MB_SECTOR_SIZE  STM_M25P80_SECTOR_SIZE+#define STM_2MB_BYTE_COUNT   STM_M25P16_BYTE_COUNT+#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT+#define STM_2MB_SECTOR_SIZE  STM_M25P16_SECTOR_SIZE+#define STM_4MB_BYTE_COUNT   STM_M25P32_BYTE_COUNT+#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT+#define STM_4MB_SECTOR_SIZE  STM_M25P32_SECTOR_SIZE+#define STM_8MB_BYTE_COUNT   STM_M25P64_BYTE_COUNT+#define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT+#define STM_8MB_SECTOR_SIZE  STM_M25P64_SECTOR_SIZE+#define STM_16MB_BYTE_COUNT   STM_M25P128_BYTE_COUNT+#define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT+#define STM_16MB_SECTOR_SIZE  STM_M25P128_SECTOR_SIZE++/*+ * ST Microelectronics Opcodes for Serial Flash+ */++#define STM_OP_WR_ENABLE       0x06     /* Write Enable */+#define STM_OP_WR_DISABLE      0x04     /* Write Disable */+#define STM_OP_RD_STATUS       0x05     /* Read Status */+#define STM_OP_WR_STATUS       0x01     /* Write Status */+#define STM_OP_RD_DATA         0x03     /* Read Data */+#define STM_OP_FAST_RD_DATA    0x0b     /* Fast Read Data */+#define STM_OP_PAGE_PGRM       0x02     /* Page Program */+#define STM_OP_SECTOR_ERASE    0xd8     /* Sector Erase */+#define STM_OP_BULK_ERASE      0xc7     /* Bulk Erase */+#define STM_OP_DEEP_PWRDOWN    0xb9     /* Deep Power-Down Mode */+#define STM_OP_RD_SIG          0xab     /* Read Electronic Signature */++#define STM_STATUS_WIP       0x01       /* Write-In-Progress */+#define STM_STATUS_WEL       0x02       /* Write Enable Latch */+#define STM_STATUS_BP0       0x04       /* Block Protect 0 */+#define STM_STATUS_BP1       0x08       /* Block Protect 1 */+#define STM_STATUS_BP2       0x10       /* Block Protect 2 */+#define STM_STATUS_SRWD      0x80       /* Status Register Write Disable */++/*+ * SPI Flash Interface Registers+ */+#define AR531XPLUS_SPI_READ     0x08000000+#define AR531XPLUS_SPI_MMR      0x11300000+#define AR531XPLUS_SPI_MMR_SIZE 12++#define AR531XPLUS_SPI_CTL      0x00+#define AR531XPLUS_SPI_OPCODE   0x04+#define AR531XPLUS_SPI_DATA     0x08++#define SPI_FLASH_READ          AR531XPLUS_SPI_READ+#define SPI_FLASH_MMR           AR531XPLUS_SPI_MMR+#define SPI_FLASH_MMR_SIZE      AR531XPLUS_SPI_MMR_SIZE+#define SPI_FLASH_CTL           AR531XPLUS_SPI_CTL+#define SPI_FLASH_OPCODE        AR531XPLUS_SPI_OPCODE+#define SPI_FLASH_DATA          AR531XPLUS_SPI_DATA++#define SPI_CTL_START           0x00000100+#define SPI_CTL_BUSY            0x00010000+#define SPI_CTL_TXCNT_MASK      0x0000000f+#define SPI_CTL_RXCNT_MASK      0x000000f0+#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff+#define SPI_CTL_SIZE_MASK       0x00060000++#define SPI_CTL_CLK_SEL_MASK    0x03000000+#define SPI_OPCODE_MASK         0x000000ff++#define SPI_STATUS_WIP		STM_STATUS_WIP++#endifdiff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar231x.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar231x.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar231x.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar231x.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,54 @@+#ifndef __AR531X_H+#define __AR531X_H++#define AR531X_MISC_IRQ_BASE		0x20+#define AR531X_GPIO_IRQ_BASE		0x30++/* Software's idea of interrupts handled by "CPU Interrupt Controller" */+#define AR531X_IRQ_NONE		MIPS_CPU_IRQ_BASE+0+#define AR531X_IRQ_CPU_CLOCK	MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */++/* Miscellaneous interrupts, which share IP6 */+#define AR531X_MISC_IRQ_NONE		AR531X_MISC_IRQ_BASE+0+#define AR531X_MISC_IRQ_TIMER		AR531X_MISC_IRQ_BASE+1+#define AR531X_MISC_IRQ_AHB_PROC	AR531X_MISC_IRQ_BASE+2+#define AR531X_MISC_IRQ_AHB_DMA		AR531X_MISC_IRQ_BASE+3+#define AR531X_MISC_IRQ_GPIO		AR531X_MISC_IRQ_BASE+4+#define AR531X_MISC_IRQ_UART0		AR531X_MISC_IRQ_BASE+5+#define AR531X_MISC_IRQ_UART0_DMA	AR531X_MISC_IRQ_BASE+6+#define AR531X_MISC_IRQ_WATCHDOG	AR531X_MISC_IRQ_BASE+7+#define AR531X_MISC_IRQ_LOCAL		AR531X_MISC_IRQ_BASE+8+#define AR531X_MISC_IRQ_SPI 		AR531X_MISC_IRQ_BASE+9+#define AR531X_MISC_IRQ_COUNT		10++/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */+#define AR531X_GPIO_IRQ_NONE            AR531X_GPIO_IRQ_BASE+0+#define AR531X_GPIO_IRQ(n)              AR531X_GPIO_IRQ_BASE+n+#define AR531X_GPIO_IRQ_COUNT           22++static inline u32+ar231x_read_reg(u32 reg)+{+	return __raw_readl((u32 *) KSEG1ADDR(reg));+}++static inline void+ar231x_write_reg(u32 reg, u32 val)+{+	__raw_writel(val, (u32 *) KSEG1ADDR(reg));+}++static inline u32+ar231x_mask_reg(u32 reg, u32 mask, u32 val)+{+	u32 ret;++	ret = ar231x_read_reg(reg);+	ret &= ~mask;+	ret |= val;+	ar231x_write_reg(reg, ret);++	return ret;+}++#endifdiff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar231x_platform.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar231x_platform.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar231x_platform.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar231x_platform.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,83 @@+#ifndef __AR531X_PLATFORM_H+#define __AR531X_PLATFORM_H++/*+ * This is board-specific data that is stored in a "fixed" location in flash.+ * It is shared across operating systems, so it should not be changed lightly.+ * The main reason we need it is in order to extract the ethernet MAC+ * address(es).+ */+struct ar231x_boarddata {+    u32 magic;                       /* board data is valid */+#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */+    u16 cksum;                       /* checksum (starting with BD_REV 2) */+    u16 rev;                         /* revision of this struct */+#define BD_REV  4+    char boardName[64];            /* Name of board */+    u16 major;                       /* Board major number */+    u16 minor;                       /* Board minor number */+    u32 flags;                      /* Board configuration */+#define BD_ENET0        0x00000001   /* ENET0 is stuffed */+#define BD_ENET1        0x00000002   /* ENET1 is stuffed */+#define BD_UART1        0x00000004   /* UART1 is stuffed */+#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */+#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */+#define BD_SYSLED       0x00000020   /* System LED stuffed */+#define BD_EXTUARTCLK   0x00000040   /* External UART clock */+#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */+#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */+#define BD_WLAN0        0x00000200   /* Enable WLAN0 */+#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */+#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */+#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */+#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */+#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */+#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */+#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */+#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */+    u16 resetConfigGpio;             /* Reset factory GPIO pin */+    u16 sysLedGpio;                  /* System LED GPIO pin */++    u32 cpuFreq;                     /* CPU core frequency in Hz */+    u32 sysFreq;                     /* System frequency in Hz */+    u32 cntFreq;                     /* Calculated C0_COUNT frequency */++    u8  wlan0_mac[6];+    u8  enet0_mac[6];+    u8  enet1_mac[6];++    u16 pciId;                       /* Pseudo PCIID for common code */+    u16 memCap;                      /* cap bank1 in MB */++    /* version 3 */+    u8  wlan1_mac[6];                 /* (ar5212) */+};++#define BOARD_CONFIG_BUFSZ		0x1000++/*+ * Platform device information for the Wireless MAC+ */+struct ar231x_board_config {+	u16 devid;++	/* board config data */+	struct ar231x_boarddata *config;++	/* radio calibration data */+	const char *radio;+};++/*+ * Platform device information for the Ethernet MAC+ */+struct ar231x_eth {+	u32 reset_base;+	u32 reset_mac;+	u32 reset_phy;+	u32 phy_base;+	struct ar231x_board_config *config;+	char *macaddr;+};++#endif /* __AR531X_PLATFORM_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar5312_regs.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar5312_regs.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/ar5312_regs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/ar5312_regs.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,236 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>+ */++#ifndef AR5312_H+#define AR5312_H++#include <asm/addrspace.h>++/*+ * IRQs+ */++#define AR5312_IRQ_WLAN0_INTRS  MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */+#define AR5312_IRQ_ENET0_INTRS  MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */+#define AR5312_IRQ_ENET1_INTRS  MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */+#define AR5312_IRQ_WLAN1_INTRS  MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */+#define AR5312_IRQ_MISC_INTRS   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */+++/* Address Map */+#define AR531X_WLAN0            0x18000000+#define AR531X_WLAN1            0x18500000+#define AR531X_ENET0            0x18100000+#define AR531X_ENET1            0x18200000+#define AR531X_SDRAMCTL         0x18300000+#define AR531X_FLASHCTL         0x18400000+#define AR531X_APBBASE		0x1c000000+#define AR531X_FLASH            0x1e000000+#define AR531X_UART0            0xbc000003      /* UART MMR */++/*+ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that+ * should be considered available.  The AR5312 supports 2 enet MACS,+ * even though many reference boards only actually use 1 of them+ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.+ * The AR2312 supports 1 enet MAC.+ */+#define AR531X_NUM_ENET_MAC             2++/*+ * Need these defines to determine true number of ethernet MACs+ */+#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */+#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */+#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */+#define AR531X_RADIO_MASK_OFF  0xc8+#define AR531X_RADIO0_MASK     0x0003+#define AR531X_RADIO1_MASK     0x000c+#define AR531X_RADIO1_S        2++/*+ * AR531X_NUM_WMAC defines the number of Wireless MACs that\+ * should be considered available.+ */+#define AR531X_NUM_WMAC                 2++/* Reset/Timer Block Address Map */+#define AR531X_RESETTMR		(AR531X_APBBASE  + 0x3000)+#define AR531X_TIMER		(AR531X_RESETTMR + 0x0000) /* countdown timer */+#define AR531X_WD_CTRL          (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */+#define AR531X_WD_TIMER         (AR531X_RESETTMR + 0x000c) /* watchdog timer */+#define AR531X_ISR		(AR531X_RESETTMR + 0x0010) /* Intr Status Reg */+#define AR531X_IMR		(AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */+#define AR531X_RESET		(AR531X_RESETTMR + 0x0020)+#define AR5312_CLOCKCTL1	(AR531X_RESETTMR + 0x0064)+#define AR5312_SCRATCH   	(AR531X_RESETTMR + 0x006c)+#define AR531X_PROCADDR		(AR531X_RESETTMR + 0x0070)+#define AR531X_PROC1		(AR531X_RESETTMR + 0x0074)+#define AR531X_DMAADDR		(AR531X_RESETTMR + 0x0078)+#define AR531X_DMA1		(AR531X_RESETTMR + 0x007c)+#define AR531X_ENABLE           (AR531X_RESETTMR + 0x0080) /* interface enb */+#define AR531X_REV		(AR531X_RESETTMR + 0x0090) /* revision */++/* AR531X_WD_CTRL register bit field definitions */+#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000+#define AR531X_WD_CTRL_NMI               0x0001+#define AR531X_WD_CTRL_RESET             0x0002++/* AR531X_ISR register bit field definitions */+#define AR531X_ISR_NONE		0x0000+#define AR531X_ISR_TIMER	0x0001+#define AR531X_ISR_AHBPROC	0x0002+#define AR531X_ISR_AHBDMA	0x0004+#define AR531X_ISR_GPIO		0x0008+#define AR531X_ISR_UART0	0x0010+#define AR531X_ISR_UART0DMA	0x0020+#define AR531X_ISR_WD		0x0040+#define AR531X_ISR_LOCAL	0x0080++/* AR531X_RESET register bit field definitions */+#define AR531X_RESET_SYSTEM     0x00000001  /* cold reset full system */+#define AR531X_RESET_PROC       0x00000002  /* cold reset MIPS core */+#define AR531X_RESET_WLAN0      0x00000004  /* cold reset WLAN MAC and BB */+#define AR531X_RESET_EPHY0      0x00000008  /* cold reset ENET0 phy */+#define AR531X_RESET_EPHY1      0x00000010  /* cold reset ENET1 phy */+#define AR531X_RESET_ENET0      0x00000020  /* cold reset ENET0 mac */+#define AR531X_RESET_ENET1      0x00000040  /* cold reset ENET1 mac */+#define AR531X_RESET_UART0      0x00000100  /* cold reset UART0 (high speed) */+#define AR531X_RESET_WLAN1      0x00000200  /* cold reset WLAN MAC/BB */+#define AR531X_RESET_APB        0x00000400  /* cold reset APB (ar5312) */+#define AR531X_RESET_WARM_PROC  0x00001000  /* warm reset MIPS core */+#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000  /* warm reset WLAN0 MAC */+#define AR531X_RESET_WARM_WLAN0_BB  0x00004000  /* warm reset WLAN0 BaseBand */+#define AR531X_RESET_NMI        0x00010000  /* send an NMI to the processor */+#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000  /* warm reset WLAN1 mac */+#define AR531X_RESET_WARM_WLAN1_BB  0x00040000  /* warm reset WLAN1 baseband */+#define AR531X_RESET_LOCAL_BUS  0x00080000  /* reset local bus */+#define AR531X_RESET_WDOG       0x00100000  /* last reset was a watchdog */++#define AR531X_RESET_WMAC0_BITS \+        AR531X_RESET_WLAN0 |\+        AR531X_RESET_WARM_WLAN0_MAC |\+        AR531X_RESET_WARM_WLAN0_BB++#define AR531X_RESERT_WMAC1_BITS \+        AR531X_RESET_WLAN1 |\+        AR531X_RESET_WARM_WLAN1_MAC |\+        AR531X_RESET_WARM_WLAN1_BB++/* AR5312_CLOCKCTL1 register bit field definitions */+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8+#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000++/* Valid for AR5312 and AR2312 */+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8+#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000++/* Valid for AR2313 */+#define AR2313_CLOCKCTL1_PREDIVIDE_MASK    0x00003000+#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT           12+#define AR2313_CLOCKCTL1_MULTIPLIER_MASK   0x001f0000+#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT          16+#define AR2313_CLOCKCTL1_DOUBLER_MASK      0x00000000+++/* AR531X_ENABLE register bit field definitions */+#define AR531X_ENABLE_WLAN0              0x0001+#define AR531X_ENABLE_ENET0              0x0002+#define AR531X_ENABLE_ENET1              0x0004+#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008   /* UART, and WLAN1 PIOs */+#define AR531X_ENABLE_WLAN1_DMA          0x0010   /* WLAN1 DMAs */+#define AR531X_ENABLE_WLAN1 \+            (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA)++/* AR531X_REV register bit field definitions */+#define AR531X_REV_WMAC_MAJ    0xf000+#define AR531X_REV_WMAC_MAJ_S  12+#define AR531X_REV_WMAC_MIN    0x0f00+#define AR531X_REV_WMAC_MIN_S  8+#define AR531X_REV_MAJ         0x00f0+#define AR531X_REV_MAJ_S       4+#define AR531X_REV_MIN         0x000f+#define AR531X_REV_MIN_S       0+#define AR531X_REV_CHIP        (AR531X_REV_MAJ|AR531X_REV_MIN)++/* Major revision numbers, bits 7..4 of Revision ID register */+#define AR531X_REV_MAJ_AR5312          0x4+#define AR531X_REV_MAJ_AR2313          0x5++/* Minor revision numbers, bits 3..0 of Revision ID register */+#define AR5312_REV_MIN_DUAL     0x0     /* Dual WLAN version */+#define AR5312_REV_MIN_SINGLE   0x1     /* Single WLAN version */++/* AR531X_FLASHCTL register bit field definitions */+#define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */+#define FLASHCTL_IDCY_S 0+#define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */+#define FLASHCTL_WST1_S 5+#define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */+#define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */+#define FLASHCTL_WST2_S 11+#define FLASHCTL_AC     0x00070000      /* Flash address check (added) */+#define FLASHCTL_AC_S   16+#define FLASHCTL_AC_128K 0x00000000+#define FLASHCTL_AC_256K 0x00010000+#define FLASHCTL_AC_512K 0x00020000+#define FLASHCTL_AC_1M   0x00030000+#define FLASHCTL_AC_2M   0x00040000+#define FLASHCTL_AC_4M   0x00050000+#define FLASHCTL_AC_8M   0x00060000+#define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */+#define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */+#define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */+#define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */+#define FLASHCTL_WP     0x04000000      /* Write protect */+#define FLASHCTL_BM     0x08000000      /* Burst mode */+#define FLASHCTL_MW     0x30000000      /* Memory width */+#define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */+#define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */+#define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */+#define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */+#define FLASHCTL_ATR    0x80000000      /* Access type == retry every */+#define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */++/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices.  */+#define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)+#define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)+#define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)++/* ARM SDRAM Controller -- just enough to determine memory size */+#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04)+#define MEM_CFG1_AC0    0x00000700      /* bank 0: SDRAM addr check (added) */+#define MEM_CFG1_AC0_S  8+#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */+#define MEM_CFG1_AC1_S  12++/* GPIO Address Map */+#define AR531X_GPIO         (AR531X_APBBASE  + 0x2000)+#define AR531X_GPIO_DO      (AR531X_GPIO + 0x00)        /* output register */+#define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)        /* intput register */+#define AR531X_GPIO_CR      (AR531X_GPIO + 0x08)        /* control register */++/* GPIO Control Register bit field definitions */+#define AR531X_GPIO_CR_M(x)    (1 << (x))                      /* mask for i/o */+#define AR531X_GPIO_CR_O(x)    (0 << (x))                      /* mask for output */+#define AR531X_GPIO_CR_I(x)    (1 << (x))                      /* mask for input */+#define AR531X_GPIO_CR_INT(x)  (1 << ((x)+8))                  /* mask for interrupt */+#define AR531X_GPIO_CR_UART(x) (1 << ((x)+16))                 /* uart multiplex */+#define AR531X_NUM_GPIO		8+++#endif+diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/cpu-feature-overrides.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/cpu-feature-overrides.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/cpu-feature-overrides.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/cpu-feature-overrides.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,84 @@+/*+ *  Atheros SoC specific CPU feature overrides+ *+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>+ *+ *  This file was derived from: include/asm-mips/cpu-features.h+ *	Copyright (C) 2003, 2004 Ralf Baechle+ *	Copyright (C) 2004 Maciej W. Rozycki+ *+ *  This program is free software; you can redistribute it and/or modify it+ *  under the terms of the GNU General Public License version 2 as published+ *  by the Free Software Foundation.+ *+ */+#ifndef __ASM_MACH_ATHEROS_CPU_FEATURE_OVERRIDES_H+#define __ASM_MACH_ATHEROS_CPU_FEATURE_OVERRIDES_H++/*+ * The ATHEROS SoCs have MIPS 4Kc/4KEc core.+ */+#define cpu_has_tlb			1+#define cpu_has_4kex			1+#define cpu_has_3k_cache		0+#define cpu_has_4k_cache		1+#define cpu_has_tx39_cache		0+#define cpu_has_sb1_cache		0+#define cpu_has_fpu			0+#define cpu_has_32fpr			0+#define cpu_has_counter			1+/* #define cpu_has_watch		? */+/* #define cpu_has_divec		? */+/* #define cpu_has_vce			? */+/* #define cpu_has_cache_cdex_p		? */+/* #define cpu_has_cache_cdex_s		? */+/* #define cpu_has_prefetch		? */+/* #define cpu_has_mcheck		? */+#define cpu_has_ejtag			1++#if !defined(CONFIG_ATHEROS_AR5312)+#  define cpu_has_llsc			1+#else+/*+ * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the+ * ll/sc instructions.+ */+#  define cpu_has_llsc			0+#endif++#define cpu_has_mips16			0+#define cpu_has_mdmx			0+#define cpu_has_mips3d			0+#define cpu_has_smartmips		0++/* #define cpu_has_vtag_icache		? */+/* #define cpu_has_dc_aliases		? */+/* #define cpu_has_ic_fills_f_dc	? */+/* #define cpu_has_pindexed_dcache	? */++/* #define cpu_icache_snoops_remote_store	? */++#define cpu_has_mips32r1		1++#if !defined(CONFIG_ATHEROS_AR5312)+#  define cpu_has_mips32r2		1+#endif++#define cpu_has_mips64r1		0+#define cpu_has_mips64r2		0++#define cpu_has_dsp			0+#define cpu_has_mipsmt			0++/* #define cpu_has_nofpuex		? */+#define cpu_has_64bits			0+#define cpu_has_64bit_zero_reg		0+#define cpu_has_64bit_gp_regs		0+#define cpu_has_64bit_addresses		0++/* #define cpu_has_inclusive_pcaches	? */++/* #define cpu_dcache_line_size()	? */+/* #define cpu_icache_line_size()	? */++#endif /* __ASM_MACH_ATHEROS_CPU_FEATURE_OVERRIDES_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/dma-coherence.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/dma-coherence.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/dma-coherence.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/dma-coherence.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,64 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>+ * Copyright (C) 2007  Felix Fietkau <nbd@openwrt.org>+ *+ */+#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H+#define __ASM_MACH_GENERIC_DMA_COHERENCE_H++#define PCI_DMA_OFFSET	0x20000000++struct device;++static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)+{+	return virt_to_phys(addr) + (dev != NULL ? PCI_DMA_OFFSET : 0);+}++static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)+{+	return page_to_phys(page) + (dev != NULL ? PCI_DMA_OFFSET : 0);+}++static inline unsigned long plat_dma_addr_to_phys(struct device *dev,+	dma_addr_t dma_addr)+{+	return (dma_addr > PCI_DMA_OFFSET ? dma_addr - PCI_DMA_OFFSET : dma_addr);+}++static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,+	size_t size, enum dma_data_direction direction)+{+}++static inline int plat_dma_supported(struct device *dev, u64 mask)+{+	return 1;+}++static inline void plat_extra_sync_for_device(struct device *dev)+{+	return;+}++static inline int plat_dma_mapping_error(struct device *dev,+					 dma_addr_t dma_addr)+{+	return 0;+}++static inline int plat_device_is_coherent(struct device *dev)+{+#ifdef CONFIG_DMA_COHERENT+	return 1;+#endif+#ifdef CONFIG_DMA_NONCOHERENT+	return 0;+#endif+}++#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/gpio.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/gpio.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/gpio.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/gpio.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,84 @@+#ifndef _ATHEROS_GPIO_H_+#define _ATHEROS_GPIO_H_++#include <ar231x.h>++struct ar231x_gpiodev {+	u32 valid_mask;+	u32 (*get_output)(void);+	u32 (*set_output)(u32 mask, u32 val);+	u32 (*get)(void);+	u32 (*set)(u32 mask, u32 val);+};++extern const struct ar231x_gpiodev *ar231x_gpiodev;++/*+ * Wrappers for the generic GPIO layer+ */++static inline int gpio_direction_input(unsigned gpio) {+	u32 mask = 1 << gpio;++	if (!(ar231x_gpiodev->valid_mask & mask))+		return -ENXIO;++	ar231x_gpiodev->set_output(mask, 0);+	return 0;+}++static inline void gpio_set_value(unsigned gpio, int value) {+	u32 mask = 1 << gpio;++	if (!(ar231x_gpiodev->valid_mask & mask))+		return;++	ar231x_gpiodev->set(mask, (!!value) * mask);+}++static inline int gpio_direction_output(unsigned gpio, int value) {+	u32 mask = 1 << gpio;++	if (!(ar231x_gpiodev->valid_mask & mask))+		return -ENXIO;++	ar231x_gpiodev->set_output(mask, mask);+	ar231x_gpiodev->set(mask, (!!value) * mask);+	return 0;+}++/* Reads the gpio pin.  Unchecked function */+static inline int gpio_get_value(unsigned gpio) {+	u32 mask = 1 << gpio;++	if (!(ar231x_gpiodev->valid_mask & mask))+		return 0;++	return !!(ar231x_gpiodev->get() & mask);+}++static inline int gpio_request(unsigned gpio, const char *label) {+	return 0;+}++static inline void gpio_free(unsigned gpio) {+}++/* Returns IRQ to attach for gpio.  Unchecked function */+static inline int gpio_to_irq(unsigned gpio) {+	return AR531X_GPIO_IRQ(gpio);+}++/* Returns gpio for IRQ attached.  Unchecked function */+static inline int irq_to_gpio(unsigned irq) {+	return (irq - (AR531X_GPIO_IRQ(0)));+}++static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)+{+	return -ENOSYS;+}++#include <asm-generic/gpio.h> /* cansleep wrappers */++#endifdiff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/reset.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/reset.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/reset.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/reset.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,6 @@+#ifndef __AR531X_RESET_H+#define __AR531X_RESET_H++void ar531x_disable_reset_button(void);++#endif /* __AR531X_RESET_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/war.h linux-2.6.37/arch/mips/include/asm/mach-ar231x/war.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-ar231x/war.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-ar231x/war.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,25 @@+/*+ * This file is subject to the terms and conditions of the GNU General Public+ * License.  See the file "COPYING" in the main directory of this archive+ * for more details.+ *+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>+ */+#ifndef __ASM_MIPS_MACH_ATHEROS_WAR_H+#define __ASM_MIPS_MACH_ATHEROS_WAR_H++#define R4600_V1_INDEX_ICACHEOP_WAR	0+#define R4600_V1_HIT_CACHEOP_WAR	0+#define R4600_V2_HIT_CACHEOP_WAR	0+#define R5432_CP0_INTERRUPT_WAR		0+#define BCM1250_M3_WAR			0+#define SIBYTE_1956_WAR			0+#define MIPS4K_ICACHE_REFILL_WAR	0+#define MIPS_CACHE_SYNC_WAR		0+#define TX49XX_ICACHE_INDEX_INV_WAR	0+#define RM9000_CDEX_SMP_WAR		0+#define ICACHE_REFILLS_WORKAROUND_WAR	0+#define R10000_LLSC_WAR			0+#define MIPS34K_MISSED_ITLB_WAR		0++#endif /* __ASM_MIPS_MACH_ATHEROS_WAR_H */diff -Nur linux-2.6.37.orig/arch/mips/kernel/cevt-r4k.c linux-2.6.37/arch/mips/kernel/cevt-r4k.c--- linux-2.6.37.orig/arch/mips/kernel/cevt-r4k.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/kernel/cevt-r4k.c	2011-05-15 19:24:57.000000000 +0200@@ -168,20 +168,23 @@ 	struct clock_event_device *cd; 	unsigned int irq; -	if (!cpu_has_counter || !mips_hpt_frequency)-		return -ENXIO;--	if (!c0_compare_int_usable())-		return -ENXIO;- 	/* 	 * With vectored interrupts things are getting platform specific. 	 * get_c0_compare_int is a hook to allow a platform to return the 	 * interrupt number of it's liking. 	 */ 	irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;-	if (get_c0_compare_int)+	if (get_c0_compare_int) { 		irq = get_c0_compare_int();+		if ((irq >= MIPS_CPU_IRQ_BASE) && (irq < MIPS_CPU_IRQ_BASE + 8))+			cp0_compare_irq = irq - MIPS_CPU_IRQ_BASE;+	}++	if (!cpu_has_counter || !mips_hpt_frequency)+		return -ENXIO;++	if (!c0_compare_int_usable())+		return -ENXIO;  	cd = &per_cpu(mips_clockevent_device, cpu); diff -Nur linux-2.6.37.orig/drivers/mtd/devices/Kconfig linux-2.6.37/drivers/mtd/devices/Kconfig--- linux-2.6.37.orig/drivers/mtd/devices/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/mtd/devices/Kconfig	2011-05-15 19:24:57.000000000 +0200@@ -112,6 +112,10 @@ 	  Set up your spi devices with the right board-specific platform data, 	  if you want to specify device partitioning. +config MTD_AR2315+	tristate "Atheros AR2315+ SPI Flash support"+	depends on ATHEROS_AR2315+ config MTD_SLRAM 	tristate "Uncached system RAM" 	helpdiff -Nur linux-2.6.37.orig/drivers/mtd/devices/Makefile linux-2.6.37/drivers/mtd/devices/Makefile--- linux-2.6.37.orig/drivers/mtd/devices/Makefile	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/mtd/devices/Makefile	2011-05-15 19:24:57.000000000 +0200@@ -17,3 +17,4 @@ obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o obj-$(CONFIG_MTD_M25P80)	+= m25p80.o obj-$(CONFIG_MTD_SST25L)	+= sst25l.o+obj-$(CONFIG_MTD_AR2315)	+= ar2315.odiff -Nur linux-2.6.37.orig/drivers/mtd/devices/ar2315.c linux-2.6.37/drivers/mtd/devices/ar2315.c--- linux-2.6.37.orig/drivers/mtd/devices/ar2315.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/mtd/devices/ar2315.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,517 @@++/*+ * MTD driver for the SPI Flash Memory support on Atheros AR2315+ *+ * Copyright (c) 2005-2006 Atheros Communications Inc.+ * Copyright (C) 2006-2007 FON Technology, SL.+ * Copyright (C) 2006-2007 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ *+ * This code is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ *+ */++#include <linux/kernel.h>+#include <linux/module.h>+#include <linux/types.h>+#include <linux/version.h>+#include <linux/errno.h>+#include <linux/slab.h>+#include <linux/mtd/mtd.h>+#include <linux/mtd/partitions.h>+#include <linux/platform_device.h>+#include <linux/sched.h>+#include <linux/root_dev.h>+#include <linux/delay.h>+#include <asm/delay.h>+#include <asm/io.h>++#include <ar2315_spiflash.h>+#include <ar231x_platform.h>+#include <ar231x.h>+++#define SPIFLASH "spiflash: "+#define busy_wait(_priv, _condition, _wait) do { \+	while (_condition) { \+		spin_unlock_bh(&_priv->lock); \+		if (_wait > 1) \+			msleep(_wait); \+		else if ((_wait == 1) && need_resched()) \+			schedule(); \+		else \+			udelay(1); \+		spin_lock_bh(&_priv->lock); \+	} \+} while (0)++enum {+	FLASH_NONE,+	FLASH_1MB,+	FLASH_2MB,+	FLASH_4MB,+	FLASH_8MB,+	FLASH_16MB,+};++/* Flash configuration table */+struct flashconfig {+	u32 byte_cnt;+	u32 sector_cnt;+	u32 sector_size;+};++const struct flashconfig flashconfig_tbl[] = {+	[FLASH_NONE] = { 0, 0, 0},+	[FLASH_1MB]  = { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE},+	[FLASH_2MB]  = { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE},+	[FLASH_4MB]  = { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE},+	[FLASH_8MB]  = { STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE},+	[FLASH_16MB] = { STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT, STM_16MB_SECTOR_SIZE}+};++/* Mapping of generic opcodes to STM serial flash opcodes */+enum {+	SPI_WRITE_ENABLE,+	SPI_WRITE_DISABLE,+	SPI_RD_STATUS,+	SPI_WR_STATUS,+	SPI_RD_DATA,+	SPI_FAST_RD_DATA,+	SPI_PAGE_PROGRAM,+	SPI_SECTOR_ERASE,+	SPI_BULK_ERASE,+	SPI_DEEP_PWRDOWN,+	SPI_RD_SIG,+};++struct opcodes {+    __u16 code;+    __s8 tx_cnt;+    __s8 rx_cnt;+};+const struct opcodes stm_opcodes[] = {+	[SPI_WRITE_ENABLE] = {STM_OP_WR_ENABLE, 1, 0},+	[SPI_WRITE_DISABLE] = {STM_OP_WR_DISABLE, 1, 0},+	[SPI_RD_STATUS] = {STM_OP_RD_STATUS, 1, 1},+	[SPI_WR_STATUS] = {STM_OP_WR_STATUS, 1, 0},+	[SPI_RD_DATA] = {STM_OP_RD_DATA, 4, 4},+	[SPI_FAST_RD_DATA] = {STM_OP_FAST_RD_DATA, 5, 0},+	[SPI_PAGE_PROGRAM] = {STM_OP_PAGE_PGRM, 8, 0},+	[SPI_SECTOR_ERASE] = {STM_OP_SECTOR_ERASE, 4, 0},+	[SPI_BULK_ERASE] = {STM_OP_BULK_ERASE, 1, 0},+	[SPI_DEEP_PWRDOWN] = {STM_OP_DEEP_PWRDOWN, 1, 0},+	[SPI_RD_SIG] = {STM_OP_RD_SIG, 4, 1},+};++/* Driver private data structure */+struct spiflash_priv {+	struct mtd_info mtd;+	void *readaddr; /* memory mapped data for read  */+	void *mmraddr;  /* memory mapped register space */+	wait_queue_head_t wq;+	spinlock_t lock;+	int state;+};++#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)++enum {+	FL_READY,+	FL_READING,+	FL_ERASING,+	FL_WRITING+};++/***************************************************************************************************/++static u32+spiflash_read_reg(struct spiflash_priv *priv, int reg)+{+	return ar231x_read_reg((u32) priv->mmraddr + reg);+}++static void+spiflash_write_reg(struct spiflash_priv *priv, int reg, u32 data)+{+	ar231x_write_reg((u32) priv->mmraddr + reg, data);+}++static u32+spiflash_wait_busy(struct spiflash_priv *priv)+{+	u32 reg;++	busy_wait(priv, (reg = spiflash_read_reg(priv, SPI_FLASH_CTL)) &+		SPI_CTL_BUSY, 0);+	return reg;+}++static u32+spiflash_sendcmd (struct spiflash_priv *priv, int opcode, u32 addr)+{+	const struct opcodes *op;+	u32 reg, mask;++	op = &stm_opcodes[opcode];+	reg = spiflash_wait_busy(priv);+	spiflash_write_reg(priv, SPI_FLASH_OPCODE,+		((u32) op->code) | (addr << 8));++	reg &= ~SPI_CTL_TX_RX_CNT_MASK;+	reg |= SPI_CTL_START | op->tx_cnt | (op->rx_cnt << 4);++	spiflash_write_reg(priv, SPI_FLASH_CTL, reg);+	spiflash_wait_busy(priv);++	if (!op->rx_cnt)+		return 0;++	reg = spiflash_read_reg(priv, SPI_FLASH_DATA);++	switch (op->rx_cnt) {+	case 1:+		mask = 0x000000ff;+		break;+	case 2:+		mask = 0x0000ffff;+		break;+	case 3:+		mask = 0x00ffffff;+		break;+	default:+		mask = 0xffffffff;+		break;+	}+	reg &= mask;++	return reg;+}+++/*+ * Probe SPI flash device+ * Function returns 0 for failure.+ * and flashconfig_tbl array index for success.+ */+static int+spiflash_probe_chip (struct spiflash_priv *priv)+{+	u32 sig;+	int flash_size;++	/* Read the signature on the flash device */+	spin_lock_bh(&priv->lock);+	sig = spiflash_sendcmd(priv, SPI_RD_SIG, 0);+	spin_unlock_bh(&priv->lock);++	switch (sig) {+	case STM_8MBIT_SIGNATURE:+		flash_size = FLASH_1MB;+		break;+	case STM_16MBIT_SIGNATURE:+		flash_size = FLASH_2MB;+		break;+	case STM_32MBIT_SIGNATURE:+		flash_size = FLASH_4MB;+		break;+	case STM_64MBIT_SIGNATURE:+		flash_size = FLASH_8MB;+		break;+	case STM_128MBIT_SIGNATURE:+		flash_size = FLASH_16MB;+		break;+	default:+		printk (KERN_WARNING SPIFLASH "Read of flash device signature failed!\n");+		return 0;+	}++	return flash_size;+}+++/* wait until the flash chip is ready and grab a lock */+static int spiflash_wait_ready(struct spiflash_priv *priv, int state)+{+	DECLARE_WAITQUEUE(wait, current);++retry:+	spin_lock_bh(&priv->lock);+	if (priv->state != FL_READY) {+		set_current_state(TASK_UNINTERRUPTIBLE);+		add_wait_queue(&priv->wq, &wait);+		spin_unlock_bh(&priv->lock);+		schedule();+		remove_wait_queue(&priv->wq, &wait);++		if(signal_pending(current))+			return 0;++		goto retry;+	}+	priv->state = state;++	return 1;+}++static inline void spiflash_done(struct spiflash_priv *priv)+{+	priv->state = FL_READY;+	spin_unlock_bh(&priv->lock);+	wake_up(&priv->wq);+}++static void+spiflash_wait_complete(struct spiflash_priv *priv, unsigned int timeout)+{+	busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &+		SPI_STATUS_WIP, timeout);+	spiflash_done(priv);+}++++static int+spiflash_erase (struct mtd_info *mtd, struct erase_info *instr)+{+	struct spiflash_priv *priv = to_spiflash(mtd);+	const struct opcodes *op;+	u32 temp, reg;++	if (instr->addr + instr->len > mtd->size)+		return -EINVAL;++	if (!spiflash_wait_ready(priv, FL_ERASING))+		return -EINTR;++	spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);+	reg = spiflash_wait_busy(priv);++	op = &stm_opcodes[SPI_SECTOR_ERASE];+	temp = ((u32)instr->addr << 8) | (u32)(op->code);+	spiflash_write_reg(priv, SPI_FLASH_OPCODE, temp);++	reg &= ~SPI_CTL_TX_RX_CNT_MASK;+	reg |= op->tx_cnt | SPI_CTL_START;+	spiflash_write_reg(priv, SPI_FLASH_CTL, reg);++	spiflash_wait_complete(priv, 20);++	instr->state = MTD_ERASE_DONE;+	mtd_erase_callback(instr);++	return 0;+}++static int+spiflash_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)+{+	struct spiflash_priv *priv = to_spiflash(mtd);+	u8 *read_addr;++	if (!len)+		return 0;++	if (from + len > mtd->size)+		return -EINVAL;++	*retlen = len;++	if (!spiflash_wait_ready(priv, FL_READING))+		return -EINTR;++	read_addr = (u8 *)(priv->readaddr + from);+	memcpy_fromio(buf, read_addr, len);+	spiflash_done(priv);++	return 0;+}++static int+spiflash_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u8 *buf)+{+	struct spiflash_priv *priv = to_spiflash(mtd);+	u32 opcode, bytes_left;++	*retlen = 0;++	if (!len)+		return 0;++	if (to + len > mtd->size)+		return -EINVAL;++	bytes_left = len;++	do {+		u32 read_len, reg, page_offset, spi_data = 0;++		read_len = min(bytes_left, sizeof(u32));++		/* 32-bit writes cannot span across a page boundary+		 * (256 bytes). This types of writes require two page+		 * program operations to handle it correctly. The STM part+		 * will write the overflow data to the beginning of the+		 * current page as opposed to the subsequent page.+		 */+		page_offset = (to & (STM_PAGE_SIZE - 1)) + read_len;++		if (page_offset > STM_PAGE_SIZE)+			read_len -= (page_offset - STM_PAGE_SIZE);++		if (!spiflash_wait_ready(priv, FL_WRITING))+			return -EINTR;++		spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);+		spi_data = 0;+		switch (read_len) {+		case 4:+			spi_data |= buf[3] << 24;+			/* fall through */+		case 3:+			spi_data |= buf[2] << 16;+			/* fall through */+		case 2:+			spi_data |= buf[1] << 8;+			/* fall through */+		case 1:+			spi_data |= buf[0] & 0xff;+			break;+		default:+			break;+		}++		spiflash_write_reg(priv, SPI_FLASH_DATA, spi_data);+		opcode = stm_opcodes[SPI_PAGE_PROGRAM].code |+			(to & 0x00ffffff) << 8;+		spiflash_write_reg(priv, SPI_FLASH_OPCODE, opcode);++		reg = spiflash_read_reg(priv, SPI_FLASH_CTL);+		reg &= ~SPI_CTL_TX_RX_CNT_MASK;+		reg |= (read_len + 4) | SPI_CTL_START;+		spiflash_write_reg(priv, SPI_FLASH_CTL, reg);++		spiflash_wait_complete(priv, 1);++		bytes_left -= read_len;+		to += read_len;+		buf += read_len;++		*retlen += read_len;+	} while (bytes_left != 0);++	return 0;+}+++#ifdef CONFIG_MTD_PARTITIONS+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "MyLoader", NULL };+#endif+++static int+spiflash_probe(struct platform_device *pdev)+{+	struct spiflash_priv *priv;+	struct mtd_partition *parts;+	struct mtd_info *mtd;+	int index, num_parts;+	int result = 0;++	priv = kzalloc(sizeof(struct spiflash_priv), GFP_KERNEL);+	spin_lock_init(&priv->lock);+	init_waitqueue_head(&priv->wq);+	priv->state = FL_READY;+	mtd = &priv->mtd;++	priv->mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE);+	if (!priv->mmraddr) {+		printk(KERN_WARNING SPIFLASH "Failed to map flash device\n");+		goto error;+	}++	index = spiflash_probe_chip(priv);+	if (!index) {+		printk (KERN_WARNING SPIFLASH "Found no serial flash device\n");+		goto error;+	}++	priv->readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt);+	if (!priv->readaddr) {+		printk (KERN_WARNING SPIFLASH "Failed to map flash device\n");+		goto error;+	}++	platform_set_drvdata(pdev, priv);+	mtd->name = "spiflash";+	mtd->type = MTD_NORFLASH;+	mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE);+	mtd->size = flashconfig_tbl[index].byte_cnt;+	mtd->erasesize = flashconfig_tbl[index].sector_size;+	mtd->writesize = 1;+	mtd->numeraseregions = 0;+	mtd->eraseregions = NULL;+	mtd->erase = spiflash_erase;+	mtd->read = spiflash_read;+	mtd->write = spiflash_write;+	mtd->owner = THIS_MODULE;++#ifdef CONFIG_MTD_PARTITIONS+	/* parse redboot partitions */+	num_parts = parse_mtd_partitions(mtd, part_probe_types, &parts, 0);+	if (!num_parts)+		goto error;++	result = add_mtd_partitions(mtd, parts, num_parts);+#endif++	return result;++error:+	if (priv->mmraddr)+		iounmap(priv->mmraddr);+	kfree(priv);+	return -ENXIO;+}++static int+spiflash_remove (struct platform_device *pdev)+{+	struct spiflash_priv *priv = platform_get_drvdata(pdev);+	struct mtd_info *mtd = &priv->mtd;++	del_mtd_partitions(mtd);+	iounmap(priv->mmraddr);+	iounmap(priv->readaddr);+	kfree(priv);++	return 0;+}++struct platform_driver spiflash_driver = {+	.driver.name = "spiflash",+	.probe = spiflash_probe,+	.remove = spiflash_remove,+};++int __init+spiflash_init (void)+{+	return platform_driver_register(&spiflash_driver);+}++void __exit+spiflash_exit (void)+{+	return platform_driver_unregister(&spiflash_driver);+}++module_init (spiflash_init);+module_exit (spiflash_exit);++MODULE_LICENSE("GPL");+MODULE_AUTHOR("OpenWrt.org, Atheros Communications Inc");+MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC");+diff -Nur linux-2.6.37.orig/drivers/mtd/redboot.c linux-2.6.37/drivers/mtd/redboot.c--- linux-2.6.37.orig/drivers/mtd/redboot.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/mtd/redboot.c	2011-05-15 19:24:57.000000000 +0200@@ -55,6 +55,22 @@ 	return 1; } +static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)+{+	struct mtd_erase_region_info *regions = mtd->eraseregions;+	int i;++	for (i = 0; i < mtd->numeraseregions; i++) {+		if (regions[i].offset ++		    regions[i].numblocks * regions[i].erasesize <= offset)+			continue;++		return regions[i].erasesize;+	}++	return mtd->erasesize;+}+ static int parse_redboot_partitions(struct mtd_info *master,                              struct mtd_partition **pparts,                              unsigned long fis_origin)@@ -70,36 +86,38 @@ 	int namelen = 0; 	int nulllen = 0; 	int numslots;+	int first_slot; 	unsigned long offset; #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED 	static char nullstring[] = "unallocated"; #endif +	buf = vmalloc(master->erasesize);+	if (!buf)+		return -ENOMEM;++ restart: 	if ( directory < 0 ) { 		offset = master->size + directory * master->erasesize;-		while (master->block_isbad && +		while (master->block_isbad && 		       master->block_isbad(master, offset)) { 			if (!offset) { 			nogood: 				printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");+				vfree(buf); 				return -EIO; 			} 			offset -= master->erasesize; 		} 	} else { 		offset = directory * master->erasesize;-		while (master->block_isbad && +		while (master->block_isbad && 		       master->block_isbad(master, offset)) { 			offset += master->erasesize; 			if (offset == master->size) 				goto nogood; 		} 	}-	buf = vmalloc(master->erasesize);--	if (!buf)-		return -ENOMEM;- 	printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n", 	       master->name, offset); @@ -171,13 +189,21 @@ 	} 	if (i == numslots) { 		/* Didn't find it */+		if (offset + master->erasesize < master->size) {+			/* not at the end of the flash yet, maybe next block :) */+			directory++;+			goto restart;+		} 		printk(KERN_NOTICE "No RedBoot partition table detected in %s\n", 		       master->name); 		ret = 0; 		goto out; 	} -	for (i = 0; i < numslots; i++) {+	first_slot = (buf[i].flash_base & (master->erasesize - 1)) /+		     sizeof(struct fis_image_desc);++	for (i = first_slot; i < first_slot + numslots; i++) { 		struct fis_list *new_fl, **prev;  		if (buf[i].name[0] == 0xff) {diff -Nur linux-2.6.37.orig/drivers/net/Kconfig linux-2.6.37/drivers/net/Kconfig--- linux-2.6.37.orig/drivers/net/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/net/Kconfig	2011-05-15 19:24:57.000000000 +0200@@ -251,6 +251,12 @@ 	help 	  Select this if your platform comes with an external 93CX6 eeprom. +config AR231X_ETHERNET+	tristate "AR231x Ethernet support"+	depends on ATHEROS_AR231X+	help+	  Support for the AR231x/531x ethernet controller+ config MACE 	tristate "MACE (Power Mac ethernet) support" 	depends on PPC_PMAC && PPC32diff -Nur linux-2.6.37.orig/drivers/net/Makefile linux-2.6.37/drivers/net/Makefile--- linux-2.6.37.orig/drivers/net/Makefile	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/net/Makefile	2011-05-15 19:24:57.000000000 +0200@@ -224,6 +224,7 @@ obj-$(CONFIG_KORINA) += korina.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o+obj-$(CONFIG_AR231X_ETHERNET) += ar231x.o obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_DECLANCE) += declance.odiff -Nur linux-2.6.37.orig/drivers/net/ar231x.c linux-2.6.37/drivers/net/ar231x.c--- linux-2.6.37.orig/drivers/net/ar231x.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/net/ar231x.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,1327 @@+/*+ * ar231x.c: Linux driver for the Atheros AR231x Ethernet device.+ *+ * Copyright (C) 2004 by Sameer Dekate <sdekate@arubanetworks.com>+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ *+ * Thanks to Atheros for providing hardware and documentation+ * enabling me to write this driver.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * Additional credits:+ * 	This code is taken from John Taylor's Sibyte driver and then+ * 	modified for the AR2313.+ */++#include <linux/module.h>+#include <linux/version.h>+#include <linux/types.h>+#include <linux/errno.h>+#include <linux/ioport.h>+#include <linux/pci.h>+#include <linux/netdevice.h>+#include <linux/etherdevice.h>+#include <linux/skbuff.h>+#include <linux/init.h>+#include <linux/delay.h>+#include <linux/mm.h>+#include <linux/highmem.h>+#include <linux/sockios.h>+#include <linux/pkt_sched.h>+#include <linux/mii.h>+#include <linux/phy.h>+#include <linux/ethtool.h>+#include <linux/ctype.h>+#include <linux/platform_device.h>++#include <net/sock.h>+#include <net/ip.h>++#include <asm/system.h>+#include <asm/io.h>+#include <asm/irq.h>+#include <asm/byteorder.h>+#include <asm/uaccess.h>+#include <asm/bootinfo.h>++#define AR2313_MTU                     1692+#define AR2313_PRIOS                   1+#define AR2313_QUEUES                  (2*AR2313_PRIOS)+#define AR2313_DESCR_ENTRIES           64+++#ifndef min+#define min(a,b)	(((a)<(b))?(a):(b))+#endif++#ifndef SMP_CACHE_BYTES+#define SMP_CACHE_BYTES	L1_CACHE_BYTES+#endif++#define AR2313_MBOX_SET_BIT  0x8++#include "ar231x.h"++/*+ * New interrupt handler strategy:+ *+ * An old interrupt handler worked using the traditional method of+ * replacing an skbuff with a new one when a packet arrives. However+ * the rx rings do not need to contain a static number of buffer+ * descriptors, thus it makes sense to move the memory allocation out+ * of the main interrupt handler and do it in a bottom half handler+ * and only allocate new buffers when the number of buffers in the+ * ring is below a certain threshold. In order to avoid starving the+ * NIC under heavy load it is however necessary to force allocation+ * when hitting a minimum threshold. The strategy for alloction is as+ * follows:+ *+ *     RX_LOW_BUF_THRES    - allocate buffers in the bottom half+ *     RX_PANIC_LOW_THRES  - we are very low on buffers, allocate+ *                           the buffers in the interrupt handler+ *     RX_RING_THRES       - maximum number of buffers in the rx ring+ *+ * One advantagous side effect of this allocation approach is that the+ * entire rx processing can be done without holding any spin lock+ * since the rx rings and registers are totally independent of the tx+ * ring and its registers.  This of course includes the kmalloc's of+ * new skb's. Thus start_xmit can run in parallel with rx processing+ * and the memory allocation on SMP systems.+ *+ * Note that running the skb reallocation in a bottom half opens up+ * another can of races which needs to be handled properly. In+ * particular it can happen that the interrupt handler tries to run+ * the reallocation while the bottom half is either running on another+ * CPU or was interrupted on the same CPU. To get around this the+ * driver uses bitops to prevent the reallocation routines from being+ * reentered.+ *+ * TX handling can also be done without holding any spin lock, wheee+ * this is fun! since tx_csm is only written to by the interrupt+ * handler.+ */++/*+ * Threshold values for RX buffer allocation - the low water marks for+ * when to start refilling the rings are set to 75% of the ring+ * sizes. It seems to make sense to refill the rings entirely from the+ * intrrupt handler once it gets below the panic threshold, that way+ * we don't risk that the refilling is moved to another CPU when the+ * one running the interrupt handler just got the slab code hot in its+ * cache.+ */+#define RX_RING_SIZE		AR2313_DESCR_ENTRIES+#define RX_PANIC_THRES	        (RX_RING_SIZE/4)+#define RX_LOW_THRES	        ((3*RX_RING_SIZE)/4)+#define CRC_LEN                 4+#define RX_OFFSET               2++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)+#define VLAN_HDR                4+#else+#define VLAN_HDR                0+#endif++#define AR2313_BUFSIZE		(AR2313_MTU + VLAN_HDR + ETH_HLEN + CRC_LEN + RX_OFFSET)++#ifdef MODULE+MODULE_LICENSE("GPL");+MODULE_AUTHOR("Sameer Dekate <sdekate@arubanetworks.com>, Imre Kaloz <kaloz@openwrt.org>, Felix Fietkau <nbd@openwrt.org>");+MODULE_DESCRIPTION("AR231x Ethernet driver");+#endif++#define virt_to_phys(x) ((u32)(x) & 0x1fffffff)++// prototypes+static void ar231x_halt(struct net_device *dev);+static void rx_tasklet_func(unsigned long data);+static void rx_tasklet_cleanup(struct net_device *dev);+static void ar231x_multicast_list(struct net_device *dev);+static void ar231x_tx_timeout(struct net_device *dev);++static int ar231x_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum);+static int ar231x_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value);+static int ar231x_mdiobus_reset(struct mii_bus *bus);+static int ar231x_mdiobus_probe (struct net_device *dev);+static void ar231x_adjust_link(struct net_device *dev);+static bool no_phy = false;++#ifndef ERR+#define ERR(fmt, args...) printk("%s: " fmt, __func__, ##args)+#endif++#ifdef CONFIG_NET_POLL_CONTROLLER+static void+ar231x_netpoll(struct net_device *dev)+{+      unsigned long flags;++      local_irq_save(flags);+      ar231x_interrupt(dev->irq, dev);+      local_irq_restore(flags);+}+#endif++static const struct net_device_ops ar231x_ops = {+	.ndo_open 		= ar231x_open,+	.ndo_stop 		= ar231x_close,+	.ndo_start_xmit 	= ar231x_start_xmit,+	.ndo_set_multicast_list = ar231x_multicast_list,+	.ndo_do_ioctl 		= ar231x_ioctl,+	.ndo_change_mtu 	= eth_change_mtu,+	.ndo_validate_addr	= eth_validate_addr,+	.ndo_set_mac_address 	= eth_mac_addr,+	.ndo_tx_timeout		= ar231x_tx_timeout,+#ifdef CONFIG_NET_POLL_CONTROLLER+	.ndo_poll_controller	= ar231x_netpoll,+#endif+};++int __init ar231x_probe(struct platform_device *pdev)+{+	struct net_device *dev;+	struct ar231x_private *sp;+	struct resource *res;+	unsigned long ar_eth_base;+	char buf[64];++	dev = alloc_etherdev(sizeof(struct ar231x_private));++	if (dev == NULL) {+		printk(KERN_ERR+			   "ar231x: Unable to allocate net_device structure!\n");+		return -ENOMEM;+	}++	platform_set_drvdata(pdev, dev);++	sp = netdev_priv(dev);+	sp->dev = dev;+	sp->cfg = pdev->dev.platform_data;++	sprintf(buf, "eth%d_membase", pdev->id);+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, buf);+	if (!res)+		return -ENODEV;++	sp->link = 0;+	ar_eth_base = res->start;++	sprintf(buf, "eth%d_irq", pdev->id);+	dev->irq = platform_get_irq_byname(pdev, buf);++	spin_lock_init(&sp->lock);++	dev->features |= NETIF_F_HIGHDMA;+	dev->netdev_ops = &ar231x_ops;++	tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev);+	tasklet_disable(&sp->rx_tasklet);++	sp->eth_regs =+		ioremap_nocache(virt_to_phys(ar_eth_base), sizeof(*sp->eth_regs));+	if (!sp->eth_regs) {+		printk("Can't remap eth registers\n");+		return (-ENXIO);+	}++	/*+	 * When there's only one MAC, PHY regs are typically on ENET0,+	 * even though the MAC might be on ENET1.+	 * Needto remap PHY regs separately in this case+	 */+	if (virt_to_phys(ar_eth_base) == virt_to_phys(sp->phy_regs))+		sp->phy_regs = sp->eth_regs;+	else {+		sp->phy_regs =+			ioremap_nocache(virt_to_phys(sp->cfg->phy_base),+							sizeof(*sp->phy_regs));+		if (!sp->phy_regs) {+			printk("Can't remap phy registers\n");+			return (-ENXIO);+		}+	}++	sp->dma_regs =+		ioremap_nocache(virt_to_phys(ar_eth_base + 0x1000),+						sizeof(*sp->dma_regs));+	dev->base_addr = (unsigned int) sp->dma_regs;+	if (!sp->dma_regs) {+		printk("Can't remap DMA registers\n");+		return (-ENXIO);+	}++	sp->int_regs = ioremap_nocache(virt_to_phys(sp->cfg->reset_base), 4);+	if (!sp->int_regs) {+		printk("Can't remap INTERRUPT registers\n");+		return (-ENXIO);+	}++	strncpy(sp->name, "Atheros AR231x", sizeof(sp->name) - 1);+	sp->name[sizeof(sp->name) - 1] = '\0';+	memcpy(dev->dev_addr, sp->cfg->macaddr, 6);++	if (ar231x_init(dev)) {+		/*+		 * ar231x_init() calls ar231x_init_cleanup() on error.+		 */+		kfree(dev);+		return -ENODEV;+	}++	if (register_netdev(dev)) {+		printk("%s: register_netdev failed\n", __func__);+		return -1;+	}++	printk("%s: %s: %02x:%02x:%02x:%02x:%02x:%02x, irq %d\n",+		   dev->name, sp->name,+		   dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],+		   dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], dev->irq);++	sp->mii_bus = mdiobus_alloc();+	if (sp->mii_bus == NULL)+		return -1;++	sp->mii_bus->priv = dev;+	sp->mii_bus->read = ar231x_mdiobus_read;+	sp->mii_bus->write = ar231x_mdiobus_write;+	sp->mii_bus->reset = ar231x_mdiobus_reset;+	sp->mii_bus->name = "ar231x_eth_mii";+	snprintf(sp->mii_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id);+	sp->mii_bus->irq = kmalloc(sizeof(int), GFP_KERNEL);+	*sp->mii_bus->irq = PHY_POLL;++	mdiobus_register(sp->mii_bus);++	/* Workaround for Micrel switch, which is only available on+	 * one PHY and cannot be configured through MDIO */+	if (!no_phy) {+		u32 phy_id = 0;+		get_phy_id(sp->mii_bus, 1, &phy_id);+		if (phy_id == 0x00221450)+			no_phy = true;+	}+	if (no_phy) {+		sp->link = 1;+		netif_carrier_on(dev);+		return 0;+	}+	no_phy = true;++	if (ar231x_mdiobus_probe(dev) != 0) {+		printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);+		rx_tasklet_cleanup(dev);+		ar231x_init_cleanup(dev);+		unregister_netdev(dev);+		kfree(dev);+		return -ENODEV;+	}++	/* start link poll timer */+	ar231x_setup_timer(dev);++	return 0;+}+++static void ar231x_multicast_list(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned int filter;++	filter = sp->eth_regs->mac_control;++	if (dev->flags & IFF_PROMISC)+		filter |= MAC_CONTROL_PR;+	else+		filter &= ~MAC_CONTROL_PR;+	if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 0))+		filter |= MAC_CONTROL_PM;+	else+		filter &= ~MAC_CONTROL_PM;++	sp->eth_regs->mac_control = filter;+}++static void rx_tasklet_cleanup(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);++	/*+	 * Tasklet may be scheduled. Need to get it removed from the list+	 * since we're about to free the struct.+	 */++	sp->unloading = 1;+	tasklet_enable(&sp->rx_tasklet);+	tasklet_kill(&sp->rx_tasklet);+}++static int __devexit ar231x_remove(struct platform_device *pdev)+{+	struct net_device *dev = platform_get_drvdata(pdev);+	struct ar231x_private *sp = netdev_priv(dev);+	rx_tasklet_cleanup(dev);+	ar231x_init_cleanup(dev);+	unregister_netdev(dev);+	if (sp->mii_bus) {+		mdiobus_unregister(sp->mii_bus);+		mdiobus_free(sp->mii_bus);+	}+	kfree(dev);+	return 0;+}+++/*+ * Restart the AR2313 ethernet controller.+ */+static int ar231x_restart(struct net_device *dev)+{+	/* disable interrupts */+	disable_irq(dev->irq);++	/* stop mac */+	ar231x_halt(dev);++	/* initialize */+	ar231x_init(dev);++	/* enable interrupts */+	enable_irq(dev->irq);++	return 0;+}++static struct platform_driver ar231x_driver = {+	.driver.name = "ar231x-eth",+	.probe = ar231x_probe,+	.remove = __devexit_p(ar231x_remove),+};++int __init ar231x_module_init(void)+{+	return platform_driver_register(&ar231x_driver);+}++void __exit ar231x_module_cleanup(void)+{+	platform_driver_unregister(&ar231x_driver);+}++module_init(ar231x_module_init);+module_exit(ar231x_module_cleanup);+++static void ar231x_free_descriptors(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	if (sp->rx_ring != NULL) {+		kfree((void *) KSEG0ADDR(sp->rx_ring));+		sp->rx_ring = NULL;+		sp->tx_ring = NULL;+	}+}+++static int ar231x_allocate_descriptors(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	int size;+	int j;+	ar231x_descr_t *space;++	if (sp->rx_ring != NULL) {+		printk("%s: already done.\n", __FUNCTION__);+		return 0;+	}++	size =+		(sizeof(ar231x_descr_t) * (AR2313_DESCR_ENTRIES * AR2313_QUEUES));+	space = kmalloc(size, GFP_KERNEL);+	if (space == NULL)+		return 1;++	/* invalidate caches */+	dma_cache_inv((unsigned int) space, size);++	/* now convert pointer to KSEG1 */+	space = (ar231x_descr_t *) KSEG1ADDR(space);++	memset((void *) space, 0, size);++	sp->rx_ring = space;+	space += AR2313_DESCR_ENTRIES;++	sp->tx_ring = space;+	space += AR2313_DESCR_ENTRIES;++	/* Initialize the transmit Descriptors */+	for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {+		ar231x_descr_t *td = &sp->tx_ring[j];+		td->status = 0;+		td->devcs = DMA_TX1_CHAINED;+		td->addr = 0;+		td->descr =+			virt_to_phys(&sp->+						 tx_ring[(j + 1) & (AR2313_DESCR_ENTRIES - 1)]);+	}++	return 0;+}+++/*+ * Generic cleanup handling data allocated during init. Used when the+ * module is unloaded or if an error occurs during initialization+ */+static void ar231x_init_cleanup(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	struct sk_buff *skb;+	int j;++	ar231x_free_descriptors(dev);++	if (sp->eth_regs)+		iounmap((void *) sp->eth_regs);+	if (sp->dma_regs)+		iounmap((void *) sp->dma_regs);++	if (sp->rx_skb) {+		for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {+			skb = sp->rx_skb[j];+			if (skb) {+				sp->rx_skb[j] = NULL;+				dev_kfree_skb(skb);+			}+		}+		kfree(sp->rx_skb);+		sp->rx_skb = NULL;+	}++	if (sp->tx_skb) {+		for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {+			skb = sp->tx_skb[j];+			if (skb) {+				sp->tx_skb[j] = NULL;+				dev_kfree_skb(skb);+			}+		}+		kfree(sp->tx_skb);+		sp->tx_skb = NULL;+	}+}++static int ar231x_setup_timer(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);++	init_timer(&sp->link_timer);++	sp->link_timer.function = ar231x_link_timer_fn;+	sp->link_timer.data = (int) dev;+	sp->link_timer.expires = jiffies + HZ;++	add_timer(&sp->link_timer);+	return 0;++}++static void ar231x_link_timer_fn(unsigned long data)+{+	struct net_device *dev = (struct net_device *) data;+	struct ar231x_private *sp = netdev_priv(dev);++	// see if the link status changed+	// This was needed to make sure we set the PHY to the+	// autonegotiated value of half or full duplex.+	ar231x_check_link(dev);++	// Loop faster when we don't have link.+	// This was needed to speed up the AP bootstrap time.+	if (sp->link == 0) {+		mod_timer(&sp->link_timer, jiffies + HZ / 2);+	} else {+		mod_timer(&sp->link_timer, jiffies + LINK_TIMER);+	}+}++static void ar231x_check_link(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	u16 phyData;++	phyData = ar231x_mdiobus_read(sp->mii_bus, sp->phy, MII_BMSR);+	if (sp->phyData != phyData) {+		if (phyData & BMSR_LSTATUS) {+			/* link is present, ready link partner ability to deterine+			   duplexity */+			int duplex = 0;+			u16 reg;++			sp->link = 1;+			reg = ar231x_mdiobus_read(sp->mii_bus, sp->phy, MII_BMCR);+			if (reg & BMCR_ANENABLE) {+				/* auto neg enabled */+				reg = ar231x_mdiobus_read(sp->mii_bus, sp->phy, MII_LPA);+				duplex = (reg & (LPA_100FULL | LPA_10FULL)) ? 1 : 0;+			} else {+				/* no auto neg, just read duplex config */+				duplex = (reg & BMCR_FULLDPLX) ? 1 : 0;+			}++			printk(KERN_INFO "%s: Configuring MAC for %s duplex\n",+				   dev->name, (duplex) ? "full" : "half");++			if (duplex) {+				/* full duplex */+				sp->eth_regs->mac_control =+					((sp->eth_regs->+					  mac_control | MAC_CONTROL_F) & ~MAC_CONTROL_DRO);+			} else {+				/* half duplex */+				sp->eth_regs->mac_control =+					((sp->eth_regs->+					  mac_control | MAC_CONTROL_DRO) & ~MAC_CONTROL_F);+			}+		} else {+			/* no link */+			sp->link = 0;+		}+		sp->phyData = phyData;+	}+}++static int ar231x_reset_reg(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned int ethsal, ethsah;+	unsigned int flags;++	*sp->int_regs |= sp->cfg->reset_mac;+	mdelay(10);+	*sp->int_regs &= ~sp->cfg->reset_mac;+	mdelay(10);+	*sp->int_regs |= sp->cfg->reset_phy;+	mdelay(10);+	*sp->int_regs &= ~sp->cfg->reset_phy;+	mdelay(10);++	sp->dma_regs->bus_mode = (DMA_BUS_MODE_SWR);+	mdelay(10);+	sp->dma_regs->bus_mode =+		((32 << DMA_BUS_MODE_PBL_SHIFT) | DMA_BUS_MODE_BLE);++	/* enable interrupts */+	sp->dma_regs->intr_ena = (DMA_STATUS_AIS |+							  DMA_STATUS_NIS |+							  DMA_STATUS_RI |+							  DMA_STATUS_TI | DMA_STATUS_FBE);+	sp->dma_regs->xmt_base = virt_to_phys(sp->tx_ring);+	sp->dma_regs->rcv_base = virt_to_phys(sp->rx_ring);+	sp->dma_regs->control =+		(DMA_CONTROL_SR | DMA_CONTROL_ST | DMA_CONTROL_SF);++	sp->eth_regs->flow_control = (FLOW_CONTROL_FCE);+	sp->eth_regs->vlan_tag = (0x8100);++	/* Enable Ethernet Interface */+	flags = (MAC_CONTROL_TE |	/* transmit enable */+			 MAC_CONTROL_PM |	/* pass mcast */+			 MAC_CONTROL_F |	/* full duplex */+			 MAC_CONTROL_HBD);	/* heart beat disabled */++	if (dev->flags & IFF_PROMISC) {	/* set promiscuous mode */+		flags |= MAC_CONTROL_PR;+	}+	sp->eth_regs->mac_control = flags;++	/* Set all Ethernet station address registers to their initial values */+	ethsah = ((((u_int) (dev->dev_addr[5]) << 8) & (u_int) 0x0000FF00) |+			  (((u_int) (dev->dev_addr[4]) << 0) & (u_int) 0x000000FF));++	ethsal = ((((u_int) (dev->dev_addr[3]) << 24) & (u_int) 0xFF000000) |+			  (((u_int) (dev->dev_addr[2]) << 16) & (u_int) 0x00FF0000) |+			  (((u_int) (dev->dev_addr[1]) << 8) & (u_int) 0x0000FF00) |+			  (((u_int) (dev->dev_addr[0]) << 0) & (u_int) 0x000000FF));++	sp->eth_regs->mac_addr[0] = ethsah;+	sp->eth_regs->mac_addr[1] = ethsal;++	mdelay(10);++	return (0);+}+++static int ar231x_init(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	int ecode = 0;++	/*+	 * Allocate descriptors+	 */+	if (ar231x_allocate_descriptors(dev)) {+		printk("%s: %s: ar231x_allocate_descriptors failed\n",+			   dev->name, __FUNCTION__);+		ecode = -EAGAIN;+		goto init_error;+	}++	/*+	 * Get the memory for the skb rings.+	 */+	if (sp->rx_skb == NULL) {+		sp->rx_skb =+			kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES,+					GFP_KERNEL);+		if (!(sp->rx_skb)) {+			printk("%s: %s: rx_skb kmalloc failed\n",+				   dev->name, __FUNCTION__);+			ecode = -EAGAIN;+			goto init_error;+		}+	}+	memset(sp->rx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES);++	if (sp->tx_skb == NULL) {+		sp->tx_skb =+			kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES,+					GFP_KERNEL);+		if (!(sp->tx_skb)) {+			printk("%s: %s: tx_skb kmalloc failed\n",+				   dev->name, __FUNCTION__);+			ecode = -EAGAIN;+			goto init_error;+		}+	}+	memset(sp->tx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES);++	/*+	 * Set tx_csm before we start receiving interrupts, otherwise+	 * the interrupt handler might think it is supposed to process+	 * tx ints before we are up and running, which may cause a null+	 * pointer access in the int handler.+	 */+	sp->rx_skbprd = 0;+	sp->cur_rx = 0;+	sp->tx_prd = 0;+	sp->tx_csm = 0;++	/*+	 * Zero the stats before starting the interface+	 */+	memset(&dev->stats, 0, sizeof(dev->stats));++	/*+	 * We load the ring here as there seem to be no way to tell the+	 * firmware to wipe the ring without re-initializing it.+	 */+	ar231x_load_rx_ring(dev, RX_RING_SIZE);++	/*+	 * Init hardware+	 */+	ar231x_reset_reg(dev);++	/*+	 * Get the IRQ+	 */+	ecode =+		request_irq(dev->irq, &ar231x_interrupt,+					IRQF_DISABLED | IRQF_SAMPLE_RANDOM,+					dev->name, dev);+	if (ecode) {+		printk(KERN_WARNING "%s: %s: Requested IRQ %d is busy\n",+			   dev->name, __FUNCTION__, dev->irq);+		goto init_error;+	}+++	tasklet_enable(&sp->rx_tasklet);++	return 0;++  init_error:+	ar231x_init_cleanup(dev);+	return ecode;+}++/*+ * Load the rx ring.+ *+ * Loading rings is safe without holding the spin lock since this is+ * done only before the device is enabled, thus no interrupts are+ * generated and by the interrupt handler/tasklet handler.+ */+static void ar231x_load_rx_ring(struct net_device *dev, int nr_bufs)+{++	struct ar231x_private *sp = netdev_priv(dev);+	short i, idx;++	idx = sp->rx_skbprd;++	for (i = 0; i < nr_bufs; i++) {+		struct sk_buff *skb;+		ar231x_descr_t *rd;+		int offset = RX_OFFSET;++		if (sp->rx_skb[idx])+			break;++		skb = netdev_alloc_skb(dev, AR2313_BUFSIZE);+		if (!skb) {+			printk("\n\n\n\n %s: No memory in system\n\n\n\n",+				   __FUNCTION__);+			break;+		}++		/*+		 * Make sure IP header starts on a fresh cache line.+		 */+		skb->dev = dev;+		if (sp->phy_dev)+			offset += sp->phy_dev->pkt_align;+		skb_reserve(skb, offset);+		sp->rx_skb[idx] = skb;++		rd = (ar231x_descr_t *) & sp->rx_ring[idx];++		/* initialize dma descriptor */+		rd->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) |+					 DMA_RX1_CHAINED);+		rd->addr = virt_to_phys(skb->data);+		rd->descr =+			virt_to_phys(&sp->+						 rx_ring[(idx + 1) & (AR2313_DESCR_ENTRIES - 1)]);+		rd->status = DMA_RX_OWN;++		idx = DSC_NEXT(idx);+	}++	if (i)+		sp->rx_skbprd = idx;++	return;+}++#define AR2313_MAX_PKTS_PER_CALL        64++static int ar231x_rx_int(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	struct sk_buff *skb, *skb_new;+	ar231x_descr_t *rxdesc;+	unsigned int status;+	u32 idx;+	int pkts = 0;+	int rval;++	idx = sp->cur_rx;++	/* process at most the entire ring and then wait for another interrupt+	 */+	while (1) {++		rxdesc = &sp->rx_ring[idx];+		status = rxdesc->status;+		if (status & DMA_RX_OWN) {+			/* SiByte owns descriptor or descr not yet filled in */+			rval = 0;+			break;+		}++		if (++pkts > AR2313_MAX_PKTS_PER_CALL) {+			rval = 1;+			break;+		}++		if ((status & DMA_RX_ERROR) && !(status & DMA_RX_LONG)) {+			dev->stats.rx_errors++;+			dev->stats.rx_dropped++;++			/* add statistics counters */+			if (status & DMA_RX_ERR_CRC)+				dev->stats.rx_crc_errors++;+			if (status & DMA_RX_ERR_COL)+				dev->stats.rx_over_errors++;+			if (status & DMA_RX_ERR_LENGTH)+				dev->stats.rx_length_errors++;+			if (status & DMA_RX_ERR_RUNT)+				dev->stats.rx_over_errors++;+			if (status & DMA_RX_ERR_DESC)+				dev->stats.rx_over_errors++;++		} else {+			/* alloc new buffer. */+			skb_new = netdev_alloc_skb(dev, AR2313_BUFSIZE + RX_OFFSET);+			if (skb_new != NULL) {+				int offset;++				skb = sp->rx_skb[idx];+				/* set skb */+				skb_put(skb,+						((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN);+				dev->stats.rx_bytes += skb->len;++				/* pass the packet to upper layers */+				if (sp->rx) {+					sp->rx(skb);+				} else {+					skb->protocol = eth_type_trans(skb, skb->dev);+					netif_rx(skb);+				}+				skb_new->dev = dev;++				/* 16 bit align */+				offset = RX_OFFSET;+				if (sp->phy_dev)+					offset += sp->phy_dev->pkt_align;+				skb_reserve(skb_new, offset);+				/* reset descriptor's curr_addr */+				rxdesc->addr = virt_to_phys(skb_new->data);++				dev->stats.rx_packets++;+				sp->rx_skb[idx] = skb_new;+			} else {+				dev->stats.rx_dropped++;+			}+		}++		rxdesc->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) |+						 DMA_RX1_CHAINED);+		rxdesc->status = DMA_RX_OWN;++		idx = DSC_NEXT(idx);+	}++	sp->cur_rx = idx;++	return rval;+}+++static void ar231x_tx_int(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	u32 idx;+	struct sk_buff *skb;+	ar231x_descr_t *txdesc;+	unsigned int status = 0;++	idx = sp->tx_csm;++	while (idx != sp->tx_prd) {+		txdesc = &sp->tx_ring[idx];++		if ((status = txdesc->status) & DMA_TX_OWN) {+			/* ar231x dma still owns descr */+			break;+		}+		/* done with this descriptor */+		dma_unmap_single(NULL, txdesc->addr,+						 txdesc->devcs & DMA_TX1_BSIZE_MASK,+						 DMA_TO_DEVICE);+		txdesc->status = 0;++		if (status & DMA_TX_ERROR) {+			dev->stats.tx_errors++;+			dev->stats.tx_dropped++;+			if (status & DMA_TX_ERR_UNDER)+				dev->stats.tx_fifo_errors++;+			if (status & DMA_TX_ERR_HB)+				dev->stats.tx_heartbeat_errors++;+			if (status & (DMA_TX_ERR_LOSS | DMA_TX_ERR_LINK))+				dev->stats.tx_carrier_errors++;+			if (status & (DMA_TX_ERR_LATE |+						  DMA_TX_ERR_COL |+						  DMA_TX_ERR_JABBER | DMA_TX_ERR_DEFER))+				dev->stats.tx_aborted_errors++;+		} else {+			/* transmit OK */+			dev->stats.tx_packets++;+		}++		skb = sp->tx_skb[idx];+		sp->tx_skb[idx] = NULL;+		idx = DSC_NEXT(idx);+		dev->stats.tx_bytes += skb->len;+		dev_kfree_skb_irq(skb);+	}++	sp->tx_csm = idx;++	return;+}+++static void rx_tasklet_func(unsigned long data)+{+	struct net_device *dev = (struct net_device *) data;+	struct ar231x_private *sp = netdev_priv(dev);++	if (sp->unloading) {+		return;+	}++	if (ar231x_rx_int(dev)) {+		tasklet_hi_schedule(&sp->rx_tasklet);+	} else {+		unsigned long flags;+		spin_lock_irqsave(&sp->lock, flags);+		sp->dma_regs->intr_ena |= DMA_STATUS_RI;+		spin_unlock_irqrestore(&sp->lock, flags);+	}+}++static void rx_schedule(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);++	sp->dma_regs->intr_ena &= ~DMA_STATUS_RI;++	tasklet_hi_schedule(&sp->rx_tasklet);+}++static irqreturn_t ar231x_interrupt(int irq, void *dev_id)+{+	struct net_device *dev = (struct net_device *) dev_id;+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned int status, enabled;++	/* clear interrupt */+	/*+	 * Don't clear RI bit if currently disabled.+	 */+	status = sp->dma_regs->status;+	enabled = sp->dma_regs->intr_ena;+	sp->dma_regs->status = status & enabled;++	if (status & DMA_STATUS_NIS) {+		/* normal status */+		/*+		 * Don't schedule rx processing if interrupt+		 * is already disabled.+		 */+		if (status & enabled & DMA_STATUS_RI) {+			/* receive interrupt */+			rx_schedule(dev);+		}+		if (status & DMA_STATUS_TI) {+			/* transmit interrupt */+			ar231x_tx_int(dev);+		}+	}++	/* abnormal status */+	if (status & (DMA_STATUS_FBE | DMA_STATUS_TPS)) {+		ar231x_restart(dev);+	}+	return IRQ_HANDLED;+}+++static int ar231x_open(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned int ethsal, ethsah;++	/* reset the hardware, in case the MAC address changed */+	ethsah = ((((u_int) (dev->dev_addr[5]) << 8) & (u_int) 0x0000FF00) |+			  (((u_int) (dev->dev_addr[4]) << 0) & (u_int) 0x000000FF));++	ethsal = ((((u_int) (dev->dev_addr[3]) << 24) & (u_int) 0xFF000000) |+			  (((u_int) (dev->dev_addr[2]) << 16) & (u_int) 0x00FF0000) |+			  (((u_int) (dev->dev_addr[1]) << 8) & (u_int) 0x0000FF00) |+			  (((u_int) (dev->dev_addr[0]) << 0) & (u_int) 0x000000FF));++	sp->eth_regs->mac_addr[0] = ethsah;+	sp->eth_regs->mac_addr[1] = ethsal;++	mdelay(10);++	dev->mtu = 1500;+	netif_start_queue(dev);++	sp->eth_regs->mac_control |= MAC_CONTROL_RE;++	return 0;+}++static void ar231x_tx_timeout(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned long flags;++	spin_lock_irqsave(&sp->lock, flags);+	ar231x_restart(dev);+	spin_unlock_irqrestore(&sp->lock, flags);+}++static void ar231x_halt(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	int j;++	tasklet_disable(&sp->rx_tasklet);++	/* kill the MAC */+	sp->eth_regs->mac_control &= ~(MAC_CONTROL_RE |	/* disable Receives */+								   MAC_CONTROL_TE);	/* disable Transmits */+	/* stop dma */+	sp->dma_regs->control = 0;+	sp->dma_regs->bus_mode = DMA_BUS_MODE_SWR;++	/* place phy and MAC in reset */+	*sp->int_regs |= (sp->cfg->reset_mac | sp->cfg->reset_phy);++	/* free buffers on tx ring */+	for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {+		struct sk_buff *skb;+		ar231x_descr_t *txdesc;++		txdesc = &sp->tx_ring[j];+		txdesc->descr = 0;++		skb = sp->tx_skb[j];+		if (skb) {+			dev_kfree_skb(skb);+			sp->tx_skb[j] = NULL;+		}+	}+}++/*+ * close should do nothing. Here's why. It's called when+ * 'ifconfig bond0 down' is run. If it calls free_irq then+ * the irq is gone forever ! When bond0 is made 'up' again,+ * the ar231x_open () does not call request_irq (). Worse,+ * the call to ar231x_halt() generates a WDOG reset due to+ * the write to 'sp->int_regs' and the box reboots.+ * Commenting this out is good since it allows the+ * system to resume when bond0 is made up again.+ */+static int ar231x_close(struct net_device *dev)+{+#if 0+	/*+	 * Disable interrupts+	 */+	disable_irq(dev->irq);++	/*+	 * Without (or before) releasing irq and stopping hardware, this+	 * is an absolute non-sense, by the way. It will be reset instantly+	 * by the first irq.+	 */+	netif_stop_queue(dev);++	/* stop the MAC and DMA engines */+	ar231x_halt(dev);++	/* release the interrupt */+	free_irq(dev->irq, dev);++#endif+	return 0;+}++static int ar231x_start_xmit(struct sk_buff *skb, struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	ar231x_descr_t *td;+	u32 idx;++	idx = sp->tx_prd;+	td = &sp->tx_ring[idx];++	if (td->status & DMA_TX_OWN) {+		/* free skbuf and lie to the caller that we sent it out */+		dev->stats.tx_dropped++;+		dev_kfree_skb(skb);++		/* restart transmitter in case locked */+		sp->dma_regs->xmt_poll = 0;+		return 0;+	}++	/* Setup the transmit descriptor. */+	td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) |+				 (DMA_TX1_LS | DMA_TX1_IC | DMA_TX1_CHAINED));+	td->addr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);+	td->status = DMA_TX_OWN;++	/* kick transmitter last */+	sp->dma_regs->xmt_poll = 0;++	sp->tx_skb[idx] = skb;+	idx = DSC_NEXT(idx);+	sp->tx_prd = idx;++	return 0;+}++static int ar231x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)+{+	struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;+	struct ar231x_private *sp = netdev_priv(dev);+	int ret;++	if (!sp->phy_dev)+		return -ENODEV;++	switch (cmd) {++	case SIOCETHTOOL:+		spin_lock_irq(&sp->lock);+		ret = phy_ethtool_ioctl(sp->phy_dev, (void *) ifr->ifr_data);+		spin_unlock_irq(&sp->lock);+		return ret;++	case SIOCSIFHWADDR:+		if (copy_from_user+			(dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))+			return -EFAULT;+		return 0;++	case SIOCGIFHWADDR:+		if (copy_to_user+			(ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))+			return -EFAULT;+		return 0;++	case SIOCGMIIPHY:+	case SIOCGMIIREG:+	case SIOCSMIIREG:+		return phy_mii_ioctl(sp->phy_dev, data, cmd);++	default:+		break;+	}++	return -EOPNOTSUPP;+}++static void ar231x_adjust_link(struct net_device *dev)+{+	struct ar231x_private *sp = netdev_priv(dev);+	unsigned int mc;++	if (!sp->phy_dev->link)+		return;++	if (sp->phy_dev->duplex != sp->oldduplex) {+		mc = readl(&sp->eth_regs->mac_control);+		mc &= ~(MAC_CONTROL_F | MAC_CONTROL_DRO);+		if (sp->phy_dev->duplex)+			mc |= MAC_CONTROL_F;+		else+			mc |= MAC_CONTROL_DRO;+		writel(mc, &sp->eth_regs->mac_control);+		sp->oldduplex = sp->phy_dev->duplex;+	}+}++#define MII_ADDR(phy, reg) \+	((reg << MII_ADDR_REG_SHIFT) | (phy << MII_ADDR_PHY_SHIFT))++static int+ar231x_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)+{+	struct net_device *const dev = bus->priv;+	struct ar231x_private *sp = netdev_priv(dev);+	volatile ETHERNET_STRUCT *ethernet = sp->phy_regs;++	ethernet->mii_addr = MII_ADDR(phy_addr, regnum);+	while (ethernet->mii_addr & MII_ADDR_BUSY);+	return (ethernet->mii_data >> MII_DATA_SHIFT);+}++static int+ar231x_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,+             u16 value)+{+	struct net_device *const dev = bus->priv;+	struct ar231x_private *sp = netdev_priv(dev);+	volatile ETHERNET_STRUCT *ethernet = sp->phy_regs;++	while (ethernet->mii_addr & MII_ADDR_BUSY);+	ethernet->mii_data = value << MII_DATA_SHIFT;+	ethernet->mii_addr = MII_ADDR(phy_addr, regnum) | MII_ADDR_WRITE;++	return 0;+}++static int ar231x_mdiobus_reset(struct mii_bus *bus)+{+	struct net_device *const dev = bus->priv;++	ar231x_reset_reg(dev);++	return 0;+}++static int ar231x_mdiobus_probe (struct net_device *dev)+{+	struct ar231x_private *const sp = netdev_priv(dev);+	struct phy_device *phydev = NULL;+	int phy_addr;++	/* find the first (lowest address) PHY on the current MAC's MII bus */+	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)+		if (sp->mii_bus->phy_map[phy_addr]) {+			phydev = sp->mii_bus->phy_map[phy_addr];+			sp->phy = phy_addr;+			break; /* break out with first one found */+		}++	if (!phydev) {+		printk (KERN_ERR "ar231x: %s: no PHY found\n", dev->name);+		return -1;+	}++	/* now we are supposed to have a proper phydev, to attach to... */+	BUG_ON(!phydev);+	BUG_ON(phydev->attached_dev);++	phydev = phy_connect(dev, dev_name(&phydev->dev), &ar231x_adjust_link, 0,+		PHY_INTERFACE_MODE_MII);++	if (IS_ERR(phydev)) {+		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);+		return PTR_ERR(phydev);+	}++	sp->rx = phydev->netif_rx;++	/* mask with MAC supported features */+	phydev->supported &= (SUPPORTED_10baseT_Half+		| SUPPORTED_10baseT_Full+		| SUPPORTED_100baseT_Half+		| SUPPORTED_100baseT_Full+		| SUPPORTED_Autoneg+		/* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */+		| SUPPORTED_MII+		| SUPPORTED_TP);++	phydev->advertising = phydev->supported;++	sp->oldduplex = -1;+	sp->phy_dev = phydev;++	printk(KERN_INFO "%s: attached PHY driver [%s] "+		"(mii_bus:phy_addr=%s)\n",+		dev->name, phydev->drv->name, dev_name(&phydev->dev));++	return 0;+}+diff -Nur linux-2.6.37.orig/drivers/net/ar231x.h linux-2.6.37/drivers/net/ar231x.h--- linux-2.6.37.orig/drivers/net/ar231x.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/net/ar231x.h	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,304 @@+/*+ * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.+ *+ * Copyright (C) 2004 by Sameer Dekate <sdekate@arubanetworks.com>+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>+ *+ * Thanks to Atheros for providing hardware and documentation+ * enabling me to write this driver.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ */++#ifndef _AR2313_H_+#define _AR2313_H_++#include <generated/autoconf.h>+#include <linux/bitops.h>+#include <asm/bootinfo.h>+#include <ar231x_platform.h>++/*+ * probe link timer - 5 secs+ */+#define LINK_TIMER    (5*HZ)++#define IS_DMA_TX_INT(X)   (((X) & (DMA_STATUS_TI)) != 0)+#define IS_DMA_RX_INT(X)   (((X) & (DMA_STATUS_RI)) != 0)+#define IS_DRIVER_OWNED(X) (((X) & (DMA_TX_OWN))    == 0)++#define AR2313_TX_TIMEOUT (HZ/4)++/*+ * Rings+ */+#define DSC_RING_ENTRIES_SIZE	(AR2313_DESCR_ENTRIES * sizeof(struct desc))+#define DSC_NEXT(idx)	        ((idx + 1) & (AR2313_DESCR_ENTRIES - 1))++#define AR2313_MBGET		2+#define AR2313_MBSET		3+#define AR2313_PCI_RECONFIG	4+#define AR2313_PCI_DUMP		5+#define AR2313_TEST_PANIC	6+#define AR2313_TEST_NULLPTR	7+#define AR2313_READ_DATA	8+#define AR2313_WRITE_DATA	9+#define AR2313_GET_VERSION	10+#define AR2313_TEST_HANG	11+#define AR2313_SYNC		12++#define DMA_RX_ERR_CRC		BIT(1)+#define DMA_RX_ERR_DRIB		BIT(2)+#define DMA_RX_ERR_MII		BIT(3)+#define DMA_RX_EV2		BIT(5)+#define DMA_RX_ERR_COL		BIT(6)+#define DMA_RX_LONG		BIT(7)+#define DMA_RX_LS		BIT(8)	/* last descriptor */+#define DMA_RX_FS		BIT(9)	/* first descriptor */+#define DMA_RX_MF		BIT(10)	/* multicast frame */+#define DMA_RX_ERR_RUNT		BIT(11)	/* runt frame */+#define DMA_RX_ERR_LENGTH	BIT(12)	/* length error */+#define DMA_RX_ERR_DESC		BIT(14)	/* descriptor error */+#define DMA_RX_ERROR		BIT(15)	/* error summary */+#define DMA_RX_LEN_MASK		0x3fff0000+#define DMA_RX_LEN_SHIFT	16+#define DMA_RX_FILT		BIT(30)+#define DMA_RX_OWN		BIT(31)	/* desc owned by DMA controller */++#define DMA_RX1_BSIZE_MASK	0x000007ff+#define DMA_RX1_BSIZE_SHIFT	0+#define DMA_RX1_CHAINED		BIT(24)+#define DMA_RX1_RER		BIT(25)++#define DMA_TX_ERR_UNDER	BIT(1)	/* underflow error */+#define DMA_TX_ERR_DEFER	BIT(2)	/* excessive deferral */+#define DMA_TX_COL_MASK		0x78+#define DMA_TX_COL_SHIFT	3+#define DMA_TX_ERR_HB		BIT(7)	/* hearbeat failure */+#define DMA_TX_ERR_COL		BIT(8)	/* excessive collisions */+#define DMA_TX_ERR_LATE		BIT(9)	/* late collision */+#define DMA_TX_ERR_LINK		BIT(10)	/* no carrier */+#define DMA_TX_ERR_LOSS		BIT(11)	/* loss of carrier */+#define DMA_TX_ERR_JABBER	BIT(14)	/* transmit jabber timeout */+#define DMA_TX_ERROR		BIT(15)	/* frame aborted */+#define DMA_TX_OWN		BIT(31)	/* descr owned by DMA controller */++#define DMA_TX1_BSIZE_MASK	0x000007ff+#define DMA_TX1_BSIZE_SHIFT	0+#define DMA_TX1_CHAINED		BIT(24)	/* chained descriptors */+#define DMA_TX1_TER		BIT(25)	/* transmit end of ring */+#define DMA_TX1_FS		BIT(29)	/* first segment */+#define DMA_TX1_LS		BIT(30)	/* last segment */+#define DMA_TX1_IC		BIT(31)	/* interrupt on completion */++#define RCVPKT_LENGTH(X)	(X  >> 16)	/* Received pkt Length */++#define MAC_CONTROL_RE		BIT(2)	/* receive enable */+#define MAC_CONTROL_TE		BIT(3)	/* transmit enable */+#define MAC_CONTROL_DC		BIT(5)	/* Deferral check */+#define MAC_CONTROL_ASTP	BIT(8)	/* Auto pad strip */+#define MAC_CONTROL_DRTY	BIT(10)	/* Disable retry */+#define MAC_CONTROL_DBF		BIT(11)	/* Disable bcast frames */+#define MAC_CONTROL_LCC		BIT(12)	/* late collision ctrl */+#define MAC_CONTROL_HP		BIT(13)	/* Hash Perfect filtering */+#define MAC_CONTROL_HASH	BIT(14)	/* Unicast hash filtering */+#define MAC_CONTROL_HO		BIT(15)	/* Hash only filtering */+#define MAC_CONTROL_PB		BIT(16)	/* Pass Bad frames */+#define MAC_CONTROL_IF		BIT(17)	/* Inverse filtering */+#define MAC_CONTROL_PR		BIT(18)	/* promiscuous mode (valid frames only) */+#define MAC_CONTROL_PM		BIT(19)	/* pass multicast */+#define MAC_CONTROL_F		BIT(20)	/* full-duplex */+#define MAC_CONTROL_DRO		BIT(23)	/* Disable Receive Own */+#define MAC_CONTROL_HBD		BIT(28)	/* heart-beat disabled (MUST BE SET) */+#define MAC_CONTROL_BLE		BIT(30)	/* big endian mode */+#define MAC_CONTROL_RA		BIT(31)	/* receive all (valid and invalid frames) */++#define MII_ADDR_BUSY		BIT(0)+#define MII_ADDR_WRITE		BIT(1)+#define MII_ADDR_REG_SHIFT	6+#define MII_ADDR_PHY_SHIFT	11+#define MII_DATA_SHIFT		0++#define FLOW_CONTROL_FCE	BIT(1)++#define DMA_BUS_MODE_SWR	BIT(0)	/* software reset */+#define DMA_BUS_MODE_BLE	BIT(7)	/* big endian mode */+#define DMA_BUS_MODE_PBL_SHIFT	8	/* programmable burst length 32 */+#define DMA_BUS_MODE_DBO	BIT(20)	/* big-endian descriptors */++#define DMA_STATUS_TI		BIT(0)	/* transmit interrupt */+#define DMA_STATUS_TPS		BIT(1)	/* transmit process stopped */+#define DMA_STATUS_TU		BIT(2)	/* transmit buffer unavailable */+#define DMA_STATUS_TJT		BIT(3)	/* transmit buffer timeout */+#define DMA_STATUS_UNF		BIT(5)	/* transmit underflow */+#define DMA_STATUS_RI		BIT(6)	/* receive interrupt */+#define DMA_STATUS_RU		BIT(7)	/* receive buffer unavailable */+#define DMA_STATUS_RPS		BIT(8)	/* receive process stopped */+#define DMA_STATUS_ETI		BIT(10)	/* early transmit interrupt */+#define DMA_STATUS_FBE		BIT(13)	/* fatal bus interrupt */+#define DMA_STATUS_ERI		BIT(14)	/* early receive interrupt */+#define DMA_STATUS_AIS		BIT(15)	/* abnormal interrupt summary */+#define DMA_STATUS_NIS		BIT(16)	/* normal interrupt summary */+#define DMA_STATUS_RS_SHIFT	17	/* receive process state */+#define DMA_STATUS_TS_SHIFT	20	/* transmit process state */+#define DMA_STATUS_EB_SHIFT	23	/* error bits */++#define DMA_CONTROL_SR		BIT(1)	/* start receive */+#define DMA_CONTROL_ST		BIT(13)	/* start transmit */+#define DMA_CONTROL_SF		BIT(21)	/* store and forward */+++typedef struct {+	volatile unsigned int status;	// OWN, Device control and status.+	volatile unsigned int devcs;	// pkt Control bits + Length+	volatile unsigned int addr;	// Current Address.+	volatile unsigned int descr;	// Next descriptor in chain.+} ar231x_descr_t;++++//+// New Combo structure for Both Eth0 AND eth1+//+typedef struct {+	volatile unsigned int mac_control;	/* 0x00 */+	volatile unsigned int mac_addr[2];	/* 0x04 - 0x08 */+	volatile unsigned int mcast_table[2];	/* 0x0c - 0x10 */+	volatile unsigned int mii_addr;	/* 0x14 */+	volatile unsigned int mii_data;	/* 0x18 */+	volatile unsigned int flow_control;	/* 0x1c */+	volatile unsigned int vlan_tag;	/* 0x20 */+	volatile unsigned int pad[7];	/* 0x24 - 0x3c */+	volatile unsigned int ucast_table[8];	/* 0x40-0x5c */++} ETHERNET_STRUCT;++/********************************************************************+ * Interrupt controller+ ********************************************************************/++typedef struct {+	volatile unsigned int wdog_control;	/* 0x08 */+	volatile unsigned int wdog_timer;	/* 0x0c */+	volatile unsigned int misc_status;	/* 0x10 */+	volatile unsigned int misc_mask;	/* 0x14 */+	volatile unsigned int global_status;	/* 0x18 */+	volatile unsigned int reserved;	/* 0x1c */+	volatile unsigned int reset_control;	/* 0x20 */+} INTERRUPT;++/********************************************************************+ * DMA controller+ ********************************************************************/+typedef struct {+	volatile unsigned int bus_mode;	/* 0x00 (CSR0) */+	volatile unsigned int xmt_poll;	/* 0x04 (CSR1) */+	volatile unsigned int rcv_poll;	/* 0x08 (CSR2) */+	volatile unsigned int rcv_base;	/* 0x0c (CSR3) */+	volatile unsigned int xmt_base;	/* 0x10 (CSR4) */+	volatile unsigned int status;	/* 0x14 (CSR5) */+	volatile unsigned int control;	/* 0x18 (CSR6) */+	volatile unsigned int intr_ena;	/* 0x1c (CSR7) */+	volatile unsigned int rcv_missed;	/* 0x20 (CSR8) */+	volatile unsigned int reserved[11];	/* 0x24-0x4c (CSR9-19) */+	volatile unsigned int cur_tx_buf_addr;	/* 0x50 (CSR20) */+	volatile unsigned int cur_rx_buf_addr;	/* 0x50 (CSR21) */+} DMA;++/*+ * Struct private for the Sibyte.+ *+ * Elements are grouped so variables used by the tx handling goes+ * together, and will go into the same cache lines etc. in order to+ * avoid cache line contention between the rx and tx handling on SMP.+ *+ * Frequently accessed variables are put at the beginning of the+ * struct to help the compiler generate better/shorter code.+ */+struct ar231x_private {+	struct net_device *dev;+	int (*rx)(struct sk_buff *skb);++	int version;+	u32 mb[2];++	volatile ETHERNET_STRUCT *phy_regs;+	volatile ETHERNET_STRUCT *eth_regs;+	volatile DMA *dma_regs;+	volatile u32 *int_regs;+	struct ar231x_eth *cfg;++	spinlock_t lock;			/* Serialise access to device */++	/*+	 * RX and TX descriptors, must be adjacent+	 */+	ar231x_descr_t *rx_ring;+	ar231x_descr_t *tx_ring;+++	struct sk_buff **rx_skb;+	struct sk_buff **tx_skb;++	/*+	 * RX elements+	 */+	u32 rx_skbprd;+	u32 cur_rx;++	/*+	 * TX elements+	 */+	u32 tx_prd;+	u32 tx_csm;++	/*+	 * Misc elements+	 */+	char name[48];+	struct {+		u32 address;+		u32 length;+		char *mapping;+	} desc;+++	struct timer_list link_timer;+	unsigned short phy;			/* merlot phy = 1, samsung phy = 0x1f */+	unsigned short mac;+	unsigned short link;		/* 0 - link down, 1 - link up */+	u16 phyData;++	struct tasklet_struct rx_tasklet;+	int unloading;++	struct phy_device *phy_dev;+	struct mii_bus *mii_bus;+	int oldduplex;+};+++/*+ * Prototypes+ */+static int ar231x_init(struct net_device *dev);+#ifdef TX_TIMEOUT+static void ar231x_tx_timeout(struct net_device *dev);+#endif+static int ar231x_restart(struct net_device *dev);+static void ar231x_load_rx_ring(struct net_device *dev, int bufs);+static irqreturn_t ar231x_interrupt(int irq, void *dev_id);+static int ar231x_open(struct net_device *dev);+static int ar231x_start_xmit(struct sk_buff *skb, struct net_device *dev);+static int ar231x_close(struct net_device *dev);+static int ar231x_ioctl(struct net_device *dev, struct ifreq *ifr,+						int cmd);+static void ar231x_init_cleanup(struct net_device *dev);+static int ar231x_setup_timer(struct net_device *dev);+static void ar231x_link_timer_fn(unsigned long data);+static void ar231x_check_link(struct net_device *dev);+#endif							/* _AR2313_H_ */diff -Nur linux-2.6.37.orig/drivers/watchdog/Kconfig linux-2.6.37/drivers/watchdog/Kconfig--- linux-2.6.37.orig/drivers/watchdog/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/watchdog/Kconfig	2011-05-15 19:24:57.000000000 +0200@@ -930,6 +930,12 @@ 	  To compile this driver as a loadable module, choose M here. 	  The module will be called bcm63xx_wdt. +config ATHEROS_WDT+	tristate "Atheros wisoc Watchdog Timer"+	depends on ATHEROS_AR231X+	help+	  Hardware driver for the Atheros wisoc Watchdog Timer.+ # PARISC Architecture  # POWERPC Architecturediff -Nur linux-2.6.37.orig/drivers/watchdog/Makefile linux-2.6.37/drivers/watchdog/Makefile--- linux-2.6.37.orig/drivers/watchdog/Makefile	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/watchdog/Makefile	2011-05-15 19:24:57.000000000 +0200@@ -116,6 +116,7 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o obj-$(CONFIG_AR7_WDT) += ar7_wdt.o+obj-$(CONFIG_ATHEROS_WDT) += ar2315-wtd.o obj-$(CONFIG_TXX9_WDT) += txx9wdt.o obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.odiff -Nur linux-2.6.37.orig/drivers/watchdog/ar2315-wtd.c linux-2.6.37/drivers/watchdog/ar2315-wtd.c--- linux-2.6.37.orig/drivers/watchdog/ar2315-wtd.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/watchdog/ar2315-wtd.c	2011-05-15 19:24:57.000000000 +0200@@ -0,0 +1,200 @@+/*+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA+ *+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>+ * Based on EP93xx and ifxmips wdt driver+ */++#include <linux/interrupt.h>+#include <linux/module.h>+#include <linux/moduleparam.h>+#include <linux/types.h>+#include <linux/miscdevice.h>+#include <linux/watchdog.h>+#include <linux/fs.h>+#include <linux/ioport.h>+#include <linux/notifier.h>+#include <linux/reboot.h>+#include <linux/init.h>+#include <linux/platform_device.h>++#include <asm/io.h>+#include <asm/uaccess.h>+#include <asm/system.h>+#include <asm/addrspace.h>+#include <ar231x_platform.h>+#include <ar2315_regs.h>+#include <ar231x.h>++#define CLOCK_RATE 40000000+#define HEARTBEAT(x) (x < 1 || x > 90)?(20):(x)++static int wdt_timeout = 20;+static int started = 0;+static int in_use = 0;++static void+ar2315_wdt_enable(void)+{+	ar231x_write_reg(AR2315_WD, wdt_timeout * CLOCK_RATE);+	ar231x_write_reg(AR2315_ISR, 0x80);+}++static ssize_t+ar2315_wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)+{+	if(len)+		ar2315_wdt_enable();+	return len;+}++static int+ar2315_wdt_open(struct inode *inode, struct file *file)+{+	if(in_use)+		return -EBUSY;+	ar2315_wdt_enable();+	in_use = started = 1;+	return nonseekable_open(inode, file);+}++static int+ar2315_wdt_release(struct inode *inode, struct file *file)+{+	in_use = 0;+	return 0;+}++static irqreturn_t+ar2315_wdt_interrupt(int irq, void *dev_id)+{+	if(started)+	{+		printk(KERN_CRIT "watchdog expired, rebooting system\n");+		emergency_restart();+	} else {+		ar231x_write_reg(AR2315_WDC, 0);+		ar231x_write_reg(AR2315_WD, 0);+		ar231x_write_reg(AR2315_ISR, 0x80);+	}+	return IRQ_HANDLED;+}++static struct watchdog_info ident = {+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,+	.identity = "ar2315 Watchdog",+};++static int+ar2315_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)+{+	int new_wdt_timeout;+	int ret = -ENOIOCTLCMD;++	switch(cmd)+	{+		case WDIOC_GETSUPPORT:+			ret = copy_to_user((struct watchdog_info __user *)arg, &ident, sizeof(ident)) ? -EFAULT : 0;+			break;++		case WDIOC_KEEPALIVE:+			ar2315_wdt_enable();+			ret = 0;+			break;++		case WDIOC_SETTIMEOUT:+			if((ret = get_user(new_wdt_timeout, (int __user *)arg)))+				break;+			wdt_timeout = HEARTBEAT(new_wdt_timeout);+			ar2315_wdt_enable();+			break;++		case WDIOC_GETTIMEOUT:+			ret = put_user(wdt_timeout, (int __user *)arg);+			break;+	}+	return ret;+}++static struct file_operations ar2315_wdt_fops = {+	.owner		= THIS_MODULE,+	.llseek		= no_llseek,+	.write		= ar2315_wdt_write,+	.unlocked_ioctl	= ar2315_wdt_ioctl,+	.open		= ar2315_wdt_open,+	.release	= ar2315_wdt_release,+};++static struct miscdevice ar2315_wdt_miscdev = {+	.minor	= WATCHDOG_MINOR,+	.name	= "watchdog",+	.fops	= &ar2315_wdt_fops,+};++static int+ar2315_wdt_probe(struct platform_device *dev)+{+	int ret = 0;++	ar2315_wdt_enable();+	ret = request_irq(AR531X_MISC_IRQ_WATCHDOG, ar2315_wdt_interrupt, IRQF_DISABLED, "ar2315_wdt", NULL);+	if(ret)+	{+		printk(KERN_ERR "ar2315wdt: failed to register inetrrupt\n");+		goto out;+	}++	ret = misc_register(&ar2315_wdt_miscdev);+	if(ret)+		printk(KERN_ERR "ar2315wdt: failed to register miscdev\n");++out:+	return ret;+}++static int+ar2315_wdt_remove(struct platform_device *dev)+{+	misc_deregister(&ar2315_wdt_miscdev);+	free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL);+	return 0;+}++static struct platform_driver ar2315_wdt_driver = {+	.probe = ar2315_wdt_probe,+	.remove = ar2315_wdt_remove,+	.driver = {+		.name = "ar2315_wdt",+		.owner = THIS_MODULE,+	},+};++static int __init+init_ar2315_wdt(void)+{+	int ret = platform_driver_register(&ar2315_wdt_driver);+	if(ret)+		printk(KERN_INFO "ar2315_wdt: error registering platfom driver!");+	return ret;+}++static void __exit+exit_ar2315_wdt(void)+{+	platform_driver_unregister(&ar2315_wdt_driver);+}++module_init(init_ar2315_wdt);+module_exit(exit_ar2315_wdt);
 |